0
# File Operations
1
2
Advanced file and directory operations including copying, moving, walking directory trees, and pattern matching. These operations work across different filesystem types and provide high-level functionality for complex file management tasks.
3
4
## Capabilities
5
6
### File Copying
7
8
Copy files and directories between filesystems with support for metadata preservation and conditional copying.
9
10
```python { .api }
11
def copy_file(src_fs: FS, src_path: str, dst_fs: FS, dst_path: str, overwrite: bool = False,
12
preserve_time: bool = False) -> None:
13
"""
14
Copy file between filesystems.
15
16
Parameters:
17
- src_fs: FS, source filesystem
18
- src_path: str, source file path
19
- dst_fs: FS, destination filesystem
20
- dst_path: str, destination file path
21
- overwrite: bool, overwrite destination if exists
22
- preserve_time: bool, preserve modification time
23
24
Raises:
25
- ResourceNotFound: If source file doesn't exist
26
- ResourceExists: If destination exists and overwrite=False
27
- DestinationExists: If destination exists and overwrite=False
28
"""
29
30
def copy_file_if(src_fs: FS, src_path: str, dst_fs: FS, dst_path: str, condition: str = 'newer') -> bool:
31
"""
32
Conditionally copy file based on condition.
33
34
Parameters:
35
- src_fs: FS, source filesystem
36
- src_path: str, source file path
37
- dst_fs: FS, destination filesystem
38
- dst_path: str, destination file path
39
- condition: str, copy condition ('newer', 'older', 'exists', 'not_exists')
40
41
Returns:
42
bool: True if file was copied
43
44
Raises:
45
- ResourceNotFound: If source file doesn't exist
46
"""
47
48
def copy_dir(src_fs: FS, src_path: str, dst_fs: FS, dst_path: str,
49
walker: Walker = None, on_copy: Callable = None) -> None:
50
"""
51
Copy directory recursively between filesystems.
52
53
Parameters:
54
- src_fs: FS, source filesystem
55
- src_path: str, source directory path
56
- dst_fs: FS, destination filesystem
57
- dst_path: str, destination directory path
58
- walker: Walker, custom walker for filtering files
59
- on_copy: Callable, callback function called for each copied file
60
61
Raises:
62
- ResourceNotFound: If source directory doesn't exist
63
- DirectoryExpected: If source is not a directory
64
"""
65
66
def copy_structure(src_fs: FS, src_path: str, dst_fs: FS, dst_path: str,
67
walker: Walker = None) -> None:
68
"""
69
Copy directory structure without files.
70
71
Parameters:
72
- src_fs: FS, source filesystem
73
- src_path: str, source directory path
74
- dst_fs: FS, destination filesystem
75
- dst_path: str, destination directory path
76
- walker: Walker, custom walker for filtering directories
77
78
Raises:
79
- ResourceNotFound: If source directory doesn't exist
80
"""
81
82
def copy_modified_time(src_fs: FS, src_path: str, dst_fs: FS, dst_path: str) -> None:
83
"""
84
Copy modification time from source to destination.
85
86
Parameters:
87
- src_fs: FS, source filesystem
88
- src_path: str, source file path
89
- dst_fs: FS, destination filesystem
90
- dst_path: str, destination file path
91
"""
92
```
93
94
### File Moving
95
96
Move files and directories between filesystems with atomic operations where possible.
97
98
```python { .api }
99
def move_file(src_fs: FS, src_path: str, dst_fs: FS, dst_path: str, overwrite: bool = False) -> None:
100
"""
101
Move file between filesystems.
102
103
Parameters:
104
- src_fs: FS, source filesystem
105
- src_path: str, source file path
106
- dst_fs: FS, destination filesystem
107
- dst_path: str, destination file path
108
- overwrite: bool, overwrite destination if exists
109
110
Raises:
111
- ResourceNotFound: If source file doesn't exist
112
- ResourceExists: If destination exists and overwrite=False
113
- CrossDeviceError: If atomic move not possible across filesystems
114
"""
115
116
def move_dir(src_fs: FS, src_path: str, dst_fs: FS, dst_path: str) -> None:
117
"""
118
Move directory recursively between filesystems.
119
120
Parameters:
121
- src_fs: FS, source filesystem
122
- src_path: str, source directory path
123
- dst_fs: FS, destination filesystem
124
- dst_path: str, destination directory path
125
126
Raises:
127
- ResourceNotFound: If source directory doesn't exist
128
- DirectoryExpected: If source is not a directory
129
- ResourceExists: If destination already exists
130
"""
131
```
132
133
### Directory Walking
134
135
Traverse directory trees with filtering and callback support.
136
137
```python { .api }
138
class Walker:
139
"""Directory tree walker with filtering capabilities."""
140
141
def __init__(self, filter: List[str] = None, exclude: List[str] = None,
142
filter_dirs: List[str] = None, exclude_dirs: List[str] = None,
143
ignore_errors: bool = False, on_error: Callable = None,
144
search: str = 'breadth', max_depth: int = None) -> None:
145
"""
146
Create directory walker.
147
148
Parameters:
149
- filter: List[str], filename patterns to include
150
- exclude: List[str], filename patterns to exclude
151
- filter_dirs: List[str], directory patterns to include
152
- exclude_dirs: List[str], directory patterns to exclude
153
- ignore_errors: bool, ignore filesystem errors
154
- on_error: Callable, error callback function
155
- search: str, search order ('breadth', 'depth')
156
- max_depth: int, maximum directory depth
157
"""
158
159
def files(self, fs: FS, path: str = '/') -> Iterator[str]:
160
"""
161
Walk files matching filters.
162
163
Parameters:
164
- fs: FS, filesystem to walk
165
- path: str, starting directory path
166
167
Returns:
168
Iterator[str]: File paths
169
"""
170
171
def dirs(self, fs: FS, path: str = '/') -> Iterator[str]:
172
"""
173
Walk directories matching filters.
174
175
Parameters:
176
- fs: FS, filesystem to walk
177
- path: str, starting directory path
178
179
Returns:
180
Iterator[str]: Directory paths
181
"""
182
183
def info(self, fs: FS, path: str = '/', namespaces: List[str] = None) -> Iterator[Tuple[str, Info]]:
184
"""
185
Walk with file info objects.
186
187
Parameters:
188
- fs: FS, filesystem to walk
189
- path: str, starting directory path
190
- namespaces: List[str], info namespaces to retrieve
191
192
Returns:
193
Iterator[Tuple[str, Info]]: (path, info) tuples
194
"""
195
196
def walk(fs: FS, path: str = '/', walker: Walker = None) -> Iterator[Tuple[str, List[str], List[str]]]:
197
"""
198
Walk directory tree like os.walk.
199
200
Parameters:
201
- fs: FS, filesystem to walk
202
- path: str, starting directory path
203
- walker: Walker, custom walker instance
204
205
Returns:
206
Iterator[Tuple[str, List[str], List[str]]]: (dirpath, dirnames, filenames) tuples
207
"""
208
```
209
210
### Pattern Matching and Globbing
211
212
Find files and directories using glob patterns and wildcards.
213
214
```python { .api }
215
class Globber:
216
"""Pattern matching for filesystem paths."""
217
218
def __init__(self, pattern: str, case_sensitive: bool = True) -> None:
219
"""
220
Create globber for pattern.
221
222
Parameters:
223
- pattern: str, glob pattern (* and ? wildcards)
224
- case_sensitive: bool, case sensitive matching
225
"""
226
227
def match(self, path: str) -> bool:
228
"""
229
Check if path matches pattern.
230
231
Parameters:
232
- path: str, path to check
233
234
Returns:
235
bool: True if path matches pattern
236
"""
237
238
class BoundGlobber:
239
"""Globber bound to specific filesystem."""
240
241
def glob(self, pattern: str, path: str = '/') -> Iterator[str]:
242
"""
243
Find paths matching glob pattern.
244
245
Parameters:
246
- pattern: str, glob pattern
247
- path: str, starting directory
248
249
Returns:
250
Iterator[str]: Matching paths
251
"""
252
253
def iglob(self, pattern: str, path: str = '/') -> Iterator[str]:
254
"""
255
Find paths matching glob pattern (iterator).
256
257
Parameters:
258
- pattern: str, glob pattern
259
- path: str, starting directory
260
261
Returns:
262
Iterator[str]: Matching paths
263
"""
264
265
# Standalone glob functions
266
def glob_match(pattern: str, name: str, case_sensitive: bool = True) -> bool:
267
"""
268
Test if name matches glob pattern.
269
270
Parameters:
271
- pattern: str, glob pattern
272
- name: str, name to test
273
- case_sensitive: bool, case sensitive matching
274
275
Returns:
276
bool: True if name matches pattern
277
"""
278
279
def imatch(pattern: str, name: str) -> bool:
280
"""
281
Case-insensitive glob pattern matching.
282
283
Parameters:
284
- pattern: str, glob pattern
285
- name: str, name to test
286
287
Returns:
288
bool: True if name matches pattern
289
"""
290
```
291
292
### Tree Display
293
294
Generate text-based tree representations of directory structures.
295
296
```python { .api }
297
def render(fs: FS, path: str = '/', encoding: str = 'unicode',
298
max_levels: int = 5, with_color: bool = False,
299
dirs_first: bool = True, file_out: IO = None) -> str:
300
"""
301
Render filesystem tree as text.
302
303
Parameters:
304
- fs: FS, filesystem to render
305
- path: str, root path for tree
306
- encoding: str, output encoding ('unicode', 'ascii')
307
- max_levels: int, maximum directory levels to show
308
- with_color: bool, use ANSI color codes
309
- dirs_first: bool, show directories before files
310
- file_out: IO, output file object
311
312
Returns:
313
str: Tree representation as text
314
315
Example output:
316
/
317
├── documents/
318
│ ├── file1.txt
319
│ └── file2.txt
320
└── photos/
321
└── image.jpg
322
"""
323
```
324
325
### Mirror Operations
326
327
Synchronize directory contents between filesystems.
328
329
```python { .api }
330
def mirror(src_fs: FS, dst_fs: FS, walker: Walker = None,
331
preserve_time: bool = False) -> None:
332
"""
333
Mirror source filesystem to destination.
334
335
Parameters:
336
- src_fs: FS, source filesystem
337
- dst_fs: FS, destination filesystem
338
- walker: Walker, custom walker for filtering
339
- preserve_time: bool, preserve modification times
340
341
Note:
342
This operation makes dst_fs identical to src_fs by copying missing files,
343
updating changed files, and removing extra files from destination.
344
"""
345
```
346
347
## Usage Examples
348
349
Copying files between different filesystem types:
350
351
```python
352
from fs import open_fs
353
from fs.copy import copy_file, copy_dir
354
355
# Copy file from local to ZIP archive
356
local_fs = open_fs('.')
357
zip_fs = open_fs('zip://backup.zip', writeable=True)
358
359
copy_file(local_fs, 'document.txt', zip_fs, 'backup/document.txt')
360
361
# Copy entire directory to memory filesystem
362
from fs.memoryfs import MemoryFS
363
mem_fs = MemoryFS()
364
copy_dir(local_fs, 'photos', mem_fs, 'backup_photos')
365
```
366
367
Walking directory trees with filtering:
368
369
```python
370
from fs import open_fs
371
from fs.walk import Walker
372
373
fs = open_fs('.')
374
375
# Find all Python files
376
walker = Walker(filter=['*.py'])
377
for path in walker.files(fs):
378
print(f"Python file: {path}")
379
380
# Find large files (using info)
381
walker = Walker()
382
for path, info in walker.info(fs, namespaces=['details']):
383
if info.size > 1024 * 1024: # > 1MB
384
print(f"Large file: {path} ({info.size} bytes)")
385
```
386
387
Pattern matching:
388
389
```python
390
from fs import open_fs
391
from fs.glob import glob_match
392
393
fs = open_fs('.')
394
395
# Check if files match patterns
396
print(glob_match('*.txt', 'readme.txt')) # True
397
print(glob_match('test_*.py', 'test_main.py')) # True
398
399
# Use bound globber for filesystem searching
400
for path in fs.glob('**/*.py'):
401
print(f"Python file: {path}")
402
```
403
404
Displaying directory trees:
405
406
```python
407
from fs import open_fs
408
from fs.tree import render
409
410
fs = open_fs('.')
411
tree_text = render(fs, max_levels=3, with_color=True)
412
print(tree_text)
413
```
414
415
## Types
416
417
```python { .api }
418
from typing import Iterator, List, Tuple, Callable, IO, Optional, Union
419
420
class Info:
421
"""File information object."""
422
pass
423
424
WalkCallback = Callable[[str], None]
425
ErrorCallback = Callable[[Exception], None]
426
```