def scan_paths(
self, rel=True, files=True, symlinks=True, dirs=True, exclude=None,
memoize=True, lookup=True) -> Dict[str, os.stat_result]:
"""Get the paths and stats of files in the directory.
Symlinks are not followed. Directory paths and their os.stat_result
objects are cached so that the filesystem is not scanned each time the
method is called.
Args:
rel: Return relative file paths.
files: Include regular files.
symlinks: Include symbolic links.
dirs: Include directories.
exclude: An iterable of relative paths of files to not include in
the output.
memoize: If true, use cached data. Otherwise, re-scan the
filesystem.
lookup: Return a defaultdict that looks up the stats of files not
already in the dictionary.
Returns:
A dict with file paths as keys and stat objects as values.
"""
exclude = set() if exclude is None else set(exclude)
if lookup:
def lookup_stat(path: str) -> os.stat_result:
full_path = os.path.join(self.path, path)
for entry, rel_path in self._sub_entries:
if entry.path == full_path:
return entry.stat()
return os.stat(full_path, follow_symlinks=False)
output = FactoryDict(lookup_stat)
else:
output = {}
if not memoize or not self._sub_entries:
self._sub_entries = []
for entry in scan_tree(self.path):
# Computing the relative path is expensive to do each time.
rel_path = os.path.relpath(entry.path, self.path)
self._sub_entries.append((entry, rel_path))
for entry, rel_path in self._sub_entries:
if entry.is_file(follow_symlinks=False) and not files:
continue
elif entry.is_dir(follow_symlinks=False) and not dirs:
continue
elif entry.is_symlink() and not symlinks:
continue
elif rel_path in exclude:
continue
else:
if rel:
output[rel_path] = entry.stat(follow_symlinks=False)
else:
output[entry.path] = entry.stat(follow_symlinks=False)
return output
评论列表
文章目录