The OS module provides new/delete/view file properties for directories or files, as well as path operations for files and directories. For example: absolute path, parent directory ... However, the operation of the OS file should also include operations such as mobile replication packaging compression decompression, which are not available in these OS modules.
The shutil in this article is the addition of file operations in the OS. --Mobile Copy packaging compression decompression,
Shutil function Function:
1 shutil.copyfileobj (FSRC, fdst[, length=16*1024])
Copy file contents to another file, you can copy the content of the specified size
Let's look at its source code first.
def copyfileobj (FSRC, FDST, length=16*1024): "" " copy data from File-like object FSRC to File-like object Fdst" "" W Hile 1: buf = fsrc.read (length) if not buf: break fdst.write (BUF)
Attention! Where fsrc,fdst are file objects, they need to be opened before they can be copied
Import shutilf1=open (' name ', ' R ') f2=open (' name_copy ', ' w+ ') shutil.copyfileobj (f1,f2,length=16*1024)
2 Shutil.copyfile (SRC,DST)
Copy file content, is not feeling the above file duplication is very troublesome? You also need to open the file with your own hand, which is not needed here, in fact, CopyFile called the Copyfileobj
def copyfile (SRC, DST, *, follow_symlinks=true): if _samefile (SRC, DST): raise Samefileerror ("{!r} and {!r} are T He same file ". Format (src, DST)) for FN in [SRC, DST]: try: st = Os.stat (FN) except OSError: # File MoS T likely does not exist pass else: # XXX, what's the other special files? (Sockets, devices ...) If Stat. S_isfifo (St.st_mode): Raise Specialfileerror ("'%s ' is a named pipe"% fn) if not follow_symlinks and os.path.is Link (src): os.symlink (Os.readlink (SRC), DST) else: with open (SRC, ' RB ') as FSRC: with open (DST, ' WB ') as FDST: copyfileobj (FSRC, FDST) return DST
Shutil.copyfile (' name ', ' name_copy_2 ') #一句就可以实现复制文件内容
3 Shutil.copymode (SRC,DST)
Copy permissions only, do not change file contents, groups, and users.
def copymode (SRC, DST, *, follow_symlinks=true): if not follow_symlinks and Os.path.islink (SRC) and Os.path.islink ( DST): if hasattr (OS, ' Lchmod '): stat_func, Chmod_func = Os.lstat, os.lchmod else: return elif Hasattr (OS, ' chmod '): stat_func, Chmod_func = Os.stat, os.chmod else: return st = Stat_func (SRC) Chmod_func (DST, Stat. S_imode (St.st_mode))
See permissions for two files first
[Root@slyoyo python_test]# ls-ltotal 4-rw-r--r--. 1 root root 05:17 test1-rwxr-xr-x. 1 root root 0 may 19:10 test2
Run command
>>> Import shutil>>> shutil.copymode (' test1 ', ' test2 ')
View Results
[Root@slyoyo python_test]# ls-ltotal 4-rw-r--r--. 1 root root 05:17 test1-rw-r--r--. 1 root root 0 may 19:10 test2
When we change the target file to a file that does not exist, the times is wrong.
>>> shutil.copymode (' test1 ', ' test3 ') Traceback (most recent call last): File "
", line 1, in< c4/>
File "/usr/local/python/lib/python3.4/shutil.py", line section, in Copymode chmod_func (DST, Stat. S_imode (St.st_mode)) Filenotfounderror: [Errno 2] No such file or directory: ' test233 '
4 Shutil.copystat (SRC,DST)
Copy all status information, including permissions, group, user, time, etc.
def copystat (SRC, DST, *, follow_symlinks=true): Def _nop (*args, Ns=none, Follow_symlinks=none): Pass # Follow Symlin KS (aka Don ' t follow symlinks) follow = Follow_symlinks or not (Os.path.islink (SRC) and Os.path.islink (DST)) if Foll OW: # Use the real function if it exists def lookup (name): Return getattr (OS, name, _NOP) Else: # Use the R EAL function only if it exists # *and* it supports follow_symlinks def lookup (name): fn = getattr (OS, name, _no P) if FN in Os.supports_follow_symlinks:return fn return _nop st = lookup ("stat") (SRC, follow_symlinks= Follow) mode = Stat. S_imode (St.st_mode) lookup ("Utime") (DST, ns= (St.st_atime_ns, St.st_mtime_ns), Follow_symlinks=follow) Try:lookup ( "chmod") (DST, mode, follow_symlinks=follow) except Notimplementederror: # If we got a notimplementederror, it ' s becaus E # * Follow_symlinks=false, # * Lchown () is unavailable, and # * either # * FCHOWNAT () is unavailable o R # * Fchownat () doesn ' t implement At_symlink_nofollow. # (it returned enosup.) # therefore we ' re out of Options--we simply cannot chown the # symlink. Give up, suppress the error. # (which is what shutil always does in this circumstance.) Pass if Hasattr (St, ' St_flags '): Try:lookup ("Chflags") (DST, St.st_flags, follow_symlinks=follow) except Oserr Or as Why:for err in ' Eopnotsupp ', ' enotsup ': If Hasattr (errno, err) and Why.errno = = GetAttr (errno, err): Break Else:raise _copyxattr (SRC, DST, Follow_symlinks=follow)
5 Shutil.copy (SRC,DST)
Copy the contents of the file and permissions, first copyfile after Copymode
def copy (SRC, DST, *, follow_symlinks=true): if Os.path.isdir (DST): DST = os.path.join (DST, Os.path.basename ( SRC)) copyfile (src, DST, follow_symlinks=follow_symlinks) copymode (src, DST, follow_symlinks=follow_ symlinks) return DST
6 Shutil.copy2 (SRC,DST)
Copies the contents of the file and all state information for the file. First CopyFile after Copystat
def copy2 (SRC, DST, *, follow_symlinks=true): "" " Copy data and all stat info (" cp-p src DST "). Return The file ' s destination. The destination is a directory. If Follow_symlinks is False, Symlinks won ' t be followed. This resembles GNU ' s "cp-p src DST". "" " If Os.path.isdir (DST): DST = os.path.join (DST, Os.path.basename (SRC)) copyfile (src, DST, follow_symlinks= Follow_symlinks) copystat (src, DST, follow_symlinks=follow_symlinks) return DST
7 shutil.copytree (SRC, DST, Symlinks=false, Ignore=none, Copy_function=copy2,ignore_dangling_symlinks=false)
Recursive copy of file contents and status information
def copytree (SRC, DST, Symlinks=false, Ignore=none, Copy_function=copy2, ignore_dangling_symlinks=false): Names = O S.listdir (SRC) If ignore is not none:ignored_names = Ignore (src, names) Else:ignored_names = set () os.makedirs ( DST) errors = [] for name in Names:if name in ignored_names:continue srcname = Os.path.join (src, name) d Stname = Os.path.join (DST, name) try:if Os.path.islink (srcname): Linkto = Os.readlink (srcname) if s Ymlinks: # We can ' t just leave it to ' copy_function ' because legacy # code with a custom ' copy_function ' May rely on Copytree # doing the right thing. Os.symlink (Linkto, DstName) copystat (SrcName, DstName, Follow_symlinks=not symlinks) Else: # Igno Re dangling symlink if the flag is on if not os.path.exists (Linkto) and Ignore_dangling_symlinks:cont Inue # Otherwise let the copy occurs. Copy2 'll raise an error If Os.path.isdir (srcname): Copytree (SrcName, DstName, symlinks, ignore, copy_function) Else:copy_function (SrcName, DstName) elif Os.path.isdir (SrcName): Copytree (SrcName, DstName, sym Links, ignore, copy_function) Else: # would raise a specialfileerror for unsupported file types Copy_fun Ction (SrcName, DstName) # Catch the Error from the recursive copytree so then we can # continue with other files Except Error as Err:errors.extend (Err.args[0]) except OSError as Why:errors.append ((SrcName, DstName, str (w hy))) Try:copystat (SRC, DST) except OSError as why: # Copying file access times could fail on Windows if GetAttr (Why, ' Winerror ', None) are None:errors.append ((SRC, DST, str (why))) if Errors:raise Error (errors) return dst# Version vulnerable to race conditions
[Root@slyoyo python_test]# tree copytree_test/copytree_test/└──test ├──test1 ├──test2 └──hahaha[ Root@slyoyo test]# ls-ltotal 0-rw-r--r--. 1 python python 0 may 19:36 hahaha-rw-r--r--. 1 python python 0 may 19:36 test1-rw-r--r--. 1 root root 0 may 19:36 test2>>> shutil.copytree (' copytree_test ', ' copytree_copy ') ' copytree_copy ' [Root@slyoyo python_test]# ls-ltotal 12drwxr-xr-x. 3 root root 4096 may 19:36 copytree_copydrwxr-xr-x. 3 root root 4096 19:36 copytree_test-rw-r-- R--. 1 python python 05:17 test1-rw-r--r--. 1 root root 0 may 19:10 Test2[root@slyoyo python_test]# Tree copytree_copy/copytree_copy/└──test ├──hahaha ├──test1 └──test2
8 Shutil.rmtree (Path, Ignore_errors=false, Onerror=none)
To delete a file recursively
def rmtree (Path, Ignore_errors=false, Onerror=none): If Ignore_errors:def onerror (*args): Pass Elif OnError is None:def onerror (*args): Raise if _use_fd_functions: # While the unsafe Rmtree works fine on bytes, the FD ba SED does not. If isinstance (path, bytes): Path = Os.fsdecode (path) # Note:to guard against Symlink races, we use the standard # Lstat ()/open ()/fstat () trick. Try:orig_st = os.lstat (path) except Exception:onerror (Os.lstat, Path, Sys.exc_info ()) Return try: FD = Os.open (path, OS. o_rdonly) except Exception:onerror (Os.lstat, Path, Sys.exc_info ()) return try:if Os.path.samestat (o Rig_st, Os.fstat (FD)): _rmtree_safe_fd (FD, Path, onerror) try:os.rmdir (path) except OSError : OnError (Os.rmdir, Path, Sys.exc_info ()) Else:try: # symlinks to directories is forbidden , see Bugs #1669 raise OSError ("Cannot call Rmtree on a syMbolic link ") except Oserror:onerror (Os.path.islink, Path, Sys.exc_info ()) Finally:os.close (FD) Else:return _rmtree_unsafe (path, onerror)
9 Shutil.move (SRC, DST)
Moving files recursively
def move (SRC, DST): REAL_DST = DST if Os.path.isdir (DST): if _samefile (SRC, DST): # We might be in a case Insensitive filesystem, # Perform the rename anyway. Os.rename (SRC, DST) return REAL_DST = Os.path.join (DST, _basename (SRC)) if Os.path.exists (REAL_DST): Raise Error ("Destination path '%s ' already exists"% REAL_DST) try: os.rename (SRC, real_dst) Except OSError: if Os.path.islink (src): linkto = Os.readlink (src) os.symlink (Linkto, REAL_DST) Os.unlink (SRC) elif os.path.isdir (src): if _DESTINSRC (SRC, DST): raise Error ("Cannot move a directory" %s ' into itself '%s '. "% (src, DST)) copytree (SRC, REAL_DST, symlinks=true) rmtree (SRC) else: Copy2 (SRC, real_dst) os.unlink (SRC) return REAL_DST
Make_archive (base_name, format, Root_dir=none, Base_dir=none, verbose=0,dry_run=0, Owner=none, Group=None, logger= None)
Compressed packaging
def make_archive (base_name, format, Root_dir=none, Base_dir=none, verbose=0, dry_run=0, Owner=none, Group=None, Logger=none): save_cwd = OS.GETCWD () if Root_dir is not none: If logger are not none: logger.debug (" Changing into '%s ', root_dir) base_name = Os.path.abspath (base_name) if not dry_run: os.chdir (Root_dir) if Base_dir is None: base_dir = os.curdir Kwargs = {' Dry_run ': dry_run, ' logger ': logger} try: Format_info = _archive_formats[format] except Keyerror: raise ValueError ("Unknown ARCHIVE format '%s '"% Format) func = format_info[0] for Arg, Val in format_info[1]: kwargs[arg] = val if format! = ' Zip ':
kwargs[' owner ' = owner kwargs[' Group '] = Group try: filename = func (base_name, Base_dir, **kwargs) finally: if Root_dir is not none: the if Logger is not none: logger.debug ("Changing Back to '%s '", Save_c WD) Os.chdir (SAVE_CWD) return filename
Base_name: Compress the packaged file name or path name
Format: Compressed or packaged in "Zip", "tar", "Bztar" or "Gztar"
Root_dir: Which directory or file to package (that is, the source file)
>>> shutil.make_archive (' tarball ', ' Gztar ', root_dir= ' copytree_test ') [Root@slyoyo python_test]# Ls-ltotal 12drwxr-xr-x. 3 root root 4096 may 19:36 copytree_copydrwxr-xr-x. 3 root root 4096 * 19:36 copytre E_test-rw-r--r--. 1 root root 0 may 21:12 tarball.tar.gz-rw-r--r--. 1 python python 05:17 test1-rw-r--r--. 1 root
root 0 May 19:10 test2