in saved web pages). The last 30 minutes spent copying is wasted time; frustrating, to
say the least!
There may be some magical Windows setting to work around this feature, but I gave
up hunting for one as soon as I realized that it would be easier to code a copier in Python.
The cpall.py script in Example 6-10 is one way to do it. With this script, I control what
happens when bad files are found—I can skip over them with Python exception han-
dlers, for instance. Moreover, this tool works with the same interface and effect on
other platforms. It seems to me, at least, that a few minutes spent writing a portable
and reusable Python script to meet a need is a better investment than looking for sol-
utions that work on only one platform (if at all).
Example 6-10. PP4E\System\Filetools\cpall.py
"""
################################################################################
Usage: "python cpall.py dirFrom dirTo".
Recursive copy of a directory tree. Works like a "cp -r dirFrom/* dirTo"
Unix command, and assumes that dirFrom and dirTo are both directories.
Was written to get around fatal error messages under Windows drag-and-drop
copies (the first bad file ends the entire copy operation immediately),
but also allows for coding more customized copy operations in Python.
################################################################################
"""
import os, sys
maxfileload = 1000000
blksize = 1024 * 500
def copyfile(pathFrom, pathTo, maxfileload=maxfileload):
"""
Copy one file pathFrom to pathTo, byte for byte;
uses binary file modes to supress Unicde decode and endline transform
"""
if os.path.getsize(pathFrom) <= maxfileload:
bytesFrom = open(pathFrom, 'rb').read() # read small file all at once
open(pathTo, 'wb').write(bytesFrom)
else:
fileFrom = open(pathFrom, 'rb') # read big files in chunks
fileTo = open(pathTo, 'wb') # need b mode for both
while True:
bytesFrom = fileFrom.read(blksize) # get one block, less at end
if not bytesFrom: break # empty after last chunk
fileTo.write(bytesFrom)
def copytree(dirFrom, dirTo, verbose=0):
"""
Copy contents of dirFrom and below to dirTo, return (files, dirs) counts;
may need to use bytes for dirnames if undecodable on other platforms;
may need to do more file type checking on Unix: skip links, fifos, etc.
"""
fcount = dcount = 0
for filename in os.listdir(dirFrom): # for files/dirs here
Copying Directory Trees | 305