shutil模块

一、主要用途

  高级的文件、文件夹、压缩包 等处理模块

二、常用方法详解

1、shutil.copyfileobj(fsrc, fdst)

功能:把一个文件的内容拷贝到另外一个文件中,可以是部分文件内容。

1 def copyfileobj(fsrc, fdst, length=16*1024):
2     """copy data from file-like object fsrc to file-like object fdst"""
3     while 1:
4         buf = fsrc.read(length)
5         if not buf:
6             break
7         fdst.write(buf)

2、shutil.copyfile(src, dst)         #src就是原文件,dst就是拷贝的文件

功能:拷贝文件,但是不拷贝所有权限    

 1 def copyfile(src, dst):
 2     """Copy data from src to dst"""
 3     if _samefile(src, dst):
 4         raise Error("`%s` and `%s` are the same file" % (src, dst))
 5 
 6     for fn in [src, dst]:
 7         try:
 8             st = os.stat(fn)
 9         except OSError:
10             # File most likely does not exist
11             pass
12         else:
13             # XXX What about other special files? (sockets, devices...)
14             if stat.S_ISFIFO(st.st_mode):
15                 raise SpecialFileError("`%s` is a named pipe" % fn)
16 
17     with open(src, 'rb') as fsrc:
18         with open(dst, 'wb') as fdst:
19             copyfileobj(fsrc, fdst)

3、shutil.copymode(src, dst)

功能:仅拷贝文件的文件权限,内容、组、用户均不变

1 def copymode(src, dst):
2     """Copy mode bits from src to dst"""
3     if hasattr(os, 'chmod'):
4         st = os.stat(src)
5         mode = stat.S_IMODE(st.st_mode)
6         os.chmod(dst, mode)

4、shutil.copystat(src, dst)

功能:拷贝文件的状态信息,如:mode bits, atime, mtime, flags

 1 def copystat(src, dst):
 2     """Copy all stat info (mode bits, atime, mtime, flags) from src to dst"""
 3     st = os.stat(src)
 4     mode = stat.S_IMODE(st.st_mode)
 5     if hasattr(os, 'utime'):
 6         os.utime(dst, (st.st_atime, st.st_mtime))
 7     if hasattr(os, 'chmod'):
 8         os.chmod(dst, mode)
 9     if hasattr(os, 'chflags') and hasattr(st, 'st_flags'):
10         try:
11             os.chflags(dst, st.st_flags)
12         except OSError, why:
13             for err in 'EOPNOTSUPP', 'ENOTSUP':
14                 if hasattr(errno, err) and why.errno == getattr(errno, err):
15                     break
16             else:
17                 raise

5、shutil.copy(src, dst)

功能:拷贝文件和文件的权限

 1 def copy(src, dst):
 2     """Copy data and mode bits ("cp src dst").
 3 
 4     The destination may be a directory.
 5 
 6     """
 7     if os.path.isdir(dst):
 8         dst = os.path.join(dst, os.path.basename(src))
 9     copyfile(src, dst)
10     copymode(src, dst)

6、shutil.copy2(src, dst)

功能:拷贝文件和文件的状态信息

 1 def copy2(src, dst):
 2     """Copy data and all stat info ("cp -p src dst").
 3 
 4     The destination may be a directory.
 5 
 6     """
 7     if os.path.isdir(dst):
 8         dst = os.path.join(dst, os.path.basename(src))
 9     copyfile(src, dst)
10     copystat(src, dst)

7、shutil.copytree(src, dst)

 功能:递归的去拷贝文件

 1 def copytree(src, dst, symlinks=False, ignore=None):
 2     """Recursively copy a directory tree using copy2().
 3 
 4     The destination directory must not already exist.
 5     If exception(s) occur, an Error is raised with a list of reasons.
 6 
 7     If the optional symlinks flag is true, symbolic links in the
 8     source tree result in symbolic links in the destination tree; if
 9     it is false, the contents of the files pointed to by symbolic
10     links are copied.
11 
12     The optional ignore argument is a callable. If given, it
13     is called with the `src` parameter, which is the directory
14     being visited by copytree(), and `names` which is the list of
15     `src` contents, as returned by os.listdir():
16 
17         callable(src, names) -> ignored_names
18 
19     Since copytree() is called recursively, the callable will be
20     called once for each directory that is copied. It returns a
21     list of names relative to the `src` directory that should
22     not be copied.
23 
24     XXX Consider this example code rather than the ultimate tool.
25 
26     """
27     names = os.listdir(src)
28     if ignore is not None:
29         ignored_names = ignore(src, names)
30     else:
31         ignored_names = set()
32 
33     os.makedirs(dst)
34     errors = []
35     for name in names:
36         if name in ignored_names:
37             continue
38         srcname = os.path.join(src, name)
39         dstname = os.path.join(dst, name)
40         try:
41             if symlinks and os.path.islink(srcname):
42                 linkto = os.readlink(srcname)
43                 os.symlink(linkto, dstname)
44             elif os.path.isdir(srcname):
45                 copytree(srcname, dstname, symlinks, ignore)
46             else:
47                 # Will raise a SpecialFileError for unsupported file types
48                 copy2(srcname, dstname)
49         # catch the Error from the recursive copytree so that we can
50         # continue with other files
51         except Error, err:
52             errors.extend(err.args[0])
53         except EnvironmentError, why:
54             errors.append((srcname, dstname, str(why)))
55     try:
56         copystat(src, dst)
57     except OSError, why:
58         if WindowsError is not None and isinstance(why, WindowsError):
59             # Copying file access times may fail on Windows
60             pass
61         else:
62             errors.append((src, dst, str(why)))
63     if errors:
64         raise Error, errors

8、shutil.rmtree(path[, ignore_errors[, onerror]])

功能:递归的去删除文件

 

 1 def rmtree(path, ignore_errors=False, onerror=None):
 2     """Recursively delete a directory tree.
 3 
 4     If ignore_errors is set, errors are ignored; otherwise, if onerror
 5     is set, it is called to handle the error with arguments (func,
 6     path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
 7     path is the argument to that function that caused it to fail; and
 8     exc_info is a tuple returned by sys.exc_info().  If ignore_errors
 9     is false and onerror is None, an exception is raised.
10 
11     """
12     if ignore_errors:
13         def onerror(*args):
14             pass
15     elif onerror is None:
16         def onerror(*args):
17             raise
18     try:
19         if os.path.islink(path):
20             # symlinks to directories are forbidden, see bug #1669
21             raise OSError("Cannot call rmtree on a symbolic link")
22     except OSError:
23         onerror(os.path.islink, path, sys.exc_info())
24         # can't continue even if onerror hook returns
25         return
26     names = []
27     try:
28         names = os.listdir(path)
29     except os.error, err:
30         onerror(os.listdir, path, sys.exc_info())
31     for name in names:
32         fullname = os.path.join(path, name)
33         try:
34             mode = os.lstat(fullname).st_mode
35         except os.error:
36             mode = 0
37         if stat.S_ISDIR(mode):
38             rmtree(fullname, ignore_errors, onerror)
39         else:
40             try:
41                 os.remove(fullname)
42             except os.error, err:
43                 onerror(os.remove, fullname, sys.exc_info())
44     try:
45         os.rmdir(path)
46     except os.error:
47         onerror(os.rmdir, path, sys.exc_info())

9、shutil.move(src, dst)

功能:递归的去移动文件

 1 def move(src, dst):
 2     """Recursively move a file or directory to another location. This is
 3     similar to the Unix "mv" command.
 4 
 5     If the destination is a directory or a symlink to a directory, the source
 6     is moved inside the directory. The destination path must not already
 7     exist.
 8 
 9     If the destination already exists but is not a directory, it may be
10     overwritten depending on os.rename() semantics.
11 
12     If the destination is on our current filesystem, then rename() is used.
13     Otherwise, src is copied to the destination and then removed.
14     A lot more could be done here...  A look at a mv.c shows a lot of
15     the issues this implementation glosses over.
16 
17     """
18     real_dst = dst
19     if os.path.isdir(dst):
20         if _samefile(src, dst):
21             # We might be on a case insensitive filesystem,
22             # perform the rename anyway.
23             os.rename(src, dst)
24             return
25 
26         real_dst = os.path.join(dst, _basename(src))
27         if os.path.exists(real_dst):
28             raise Error, "Destination path '%s' already exists" % real_dst
29     try:
30         os.rename(src, real_dst)
31     except OSError:
32         if os.path.isdir(src):
33             if _destinsrc(src, dst):
34                 raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst)
35             copytree(src, real_dst, symlinks=True)
36             rmtree(src)
37         else:
38             copy2(src, real_dst)
39             os.unlink(src)

 

三、压缩包,解压

1、shutil.make_archive((base_name, format, root_dir=None,base_dir=None,verbose=0,dry=0,owner=None,group=None,logger=None)

功能:创建压缩包并且返回文件路径,例如:zip,tar

base_name : 压缩包的文件名,也可以是压缩包的路径。只是文件名,则保存当前目录,否则保存到指定路径。

如:www                       ==>保存到当前路径

   :C:\Users\Administrator\www  ===>保存至C:\Users\Administrator\

format:压缩包种类,’zip’,’tar’,’bztar’,’gztar’

root_dir:需要压缩的文件夹路径(默认当前路径)

owner:用户,默认当前用户

group:组,默认当前组

logger:用于记录日志,通常是logging.Logger对象 #还有讲到,后面会补

 

 1 def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0,
 2                  dry_run=0, owner=None, group=None, logger=None):
 3     """Create an archive file (eg. zip or tar).
 4 
 5     'base_name' is the name of the file to create, minus any format-specific
 6     extension; 'format' is the archive format: one of "zip", "tar", "bztar"
 7     or "gztar".
 8 
 9     'root_dir' is a directory that will be the root directory of the
10     archive; ie. we typically chdir into 'root_dir' before creating the
11     archive.  'base_dir' is the directory where we start archiving from;
12     ie. 'base_dir' will be the common prefix of all files and
13     directories in the archive.  'root_dir' and 'base_dir' both default
14     to the current directory.  Returns the name of the archive file.
15 
16     'owner' and 'group' are used when creating a tar archive. By default,
17     uses the current owner and group.
18     """
19     save_cwd = os.getcwd()
20     if root_dir is not None:
21         if logger is not None:
22             logger.debug("changing into '%s'", root_dir)
23         base_name = os.path.abspath(base_name)
24         if not dry_run:
25             os.chdir(root_dir)
26 
27     if base_dir is None:
28         base_dir = os.curdir
29 
30     kwargs = {'dry_run': dry_run, 'logger': logger}
31 
32     try:
33         format_info = _ARCHIVE_FORMATS[format]
34     except KeyError:
35         raise ValueError, "unknown archive format '%s'" % format
36 
37     func = format_info[0]
38     for arg, val in format_info[1]:
39         kwargs[arg] = val
40 
41     if format != 'zip':
42         kwargs['owner'] = owner
43         kwargs['group'] = group
44 
45     try:
46         filename = func(base_name, base_dir, **kwargs)
47     finally:
48         if root_dir is not None:
49             if logger is not None:
50                 logger.debug("changing back to '%s'", save_cwd)
51             os.chdir(save_cwd)
52 
53     return filename

 

2、zipfile

功能:以zip的形式压缩文件,注意了这个只能压缩文件,不能压缩目录,如果压缩,也只能显示空目录。

 1 import zipfile
 2  
 3 # 压缩
 4 z = zipfile.ZipFile('qianduoduo.zip', 'w')
 5 z.write('info')  #写入当前环境变量内的文件
 6 z.write('shutil_test.py')
 7 z.close()   #关闭
 8  
 9 # 解压
10 z = zipfile.ZipFile('qianduoduo.zip', 'r')
11 z.extractall()   #解压所有压缩包内的文件
12 z.close()

 

3、tarfile

功能:以tar的形式打包文件,这边能打包所以文件,包括目录

 1 import tarfile
 2 
 3 # 压缩
 4 import tarfile
 5 tar = tarfile.open("钱多多.tar","w")
 6 tar.add("f:haha\钱多多.zip")
 7 tar.add("f:haha\钱多多1.tar")
 8 tar.close()
 9 #解压
10 tar = tarfile.open("钱多多.tar",'r')
11 tar.extractall()  #可以添加路径
12 tar.close()

 

小结:

  1、tar打包不会压缩文件,所以文件的大小没有变

  2、zip才会压缩,所以压缩后的文件大小会变小

  3、一般情况下是先打包再压缩

posted on 2018-01-10 22:45 钱多多的妖孽人生 阅读() 评论() 编辑 收藏
版权声明:本文为ManyQian原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ManyQian/p/8261419.html