首页 后端开发 Python教程 Python中shutil模块的常用文件操作函数用法示例

Python中shutil模块的常用文件操作函数用法示例

Jul 22, 2016 am 08:56 AM
python shutil 文件

os模块提供了对目录或者文件的新建/删除/查看文件属性,还提供了对文件以及目录的路径操作。比如说:绝对路径,父目录……  但是,os文件的操作还应该包含移动 复制  打包 压缩 解压等操作,这些os模块都没有提供。
而本文所讲的shutil则就是对os中文件操作的补充。--移动 复制  打包 压缩 解压,
shutil函数功能:
1  shutil.copyfileobj(fsrc, fdst[, length=16*1024])
copy文件内容到另一个文件,可以copy指定大小的内容
先来看看其源代码。

def copyfileobj(fsrc, fdst, length=16*1024):
  """copy data from file-like object fsrc to file-like object fdst"""
  while 1:
    buf = fsrc.read(length)
    if not buf:
      break
    fdst.write(buf)
登录后复制

注意! 在其中fsrc,fdst都是文件对象,都需要打开后才能进行复制操作

import shutil
f1=open('name','r')
f2=open('name_copy','w+')
shutil.copyfileobj(f1,f2,length=16*1024)
登录后复制


2 shutil.copyfile(src,dst)
copy文件内容,是不是感觉上面的文件复制很麻烦?还需要自己手动用open函数打开文件,在这里就不需要了,事实上,copyfile调用了copyfileobj

def copyfile(src, dst, *, follow_symlinks=True):
  if _samefile(src, dst):
    raise SameFileError("{!r} and {!r} are the same file".format(src, dst))
  for fn in [src, dst]:
    try:
      st = os.stat(fn)
    except OSError:
      # File most likely does not exist
      pass
    else:
      # XXX What about 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.islink(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权限,不更改文件内容,组和用户。

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))
登录后复制

先看两个文件的权限

[root@slyoyo python_test]# ls -l
total 4
-rw-r--r--. 1 root root 79 May 14 05:17 test1
-rwxr-xr-x. 1 root root 0 May 14 19:10 test2
登录后复制

运行命令

>>> import shutil
>>> shutil.copymode('test1','test2')
登录后复制

查看结果

[root@slyoyo python_test]# ls -l
total 4
-rw-r--r--. 1 root root 79 May 14 05:17 test1
-rw-r--r--. 1 root root 0 May 14 19:10 test2
登录后复制

当我们将目标文件换为一个不存在的文件时报错

>>> shutil.copymode('test1','test3')  
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "/usr/local/python/lib/python3.4/shutil.py", line 132, 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)
复制所有的状态信息,包括权限,组,用户,时间等

def copystat(src, dst, *, follow_symlinks=True):

  def _nop(*args, ns=None, follow_symlinks=None):
    pass
  # follow symlinks (aka don't not follow symlinks)
  follow = follow_symlinks or not (os.path.islink(src) and os.path.islink(dst))
  if follow:
    # use the real function if it exists
    def lookup(name):
      return getattr(os, name, _nop)
  else:
    # use the real function only if it exists
    # *and* it supports follow_symlinks
    def lookup(name):
      fn = getattr(os, name, _nop)
      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 because
    #  * follow_symlinks=False,
    #  * lchown() is unavailable, and
    #  * either
    #    * fchownat() is unavailable or
    #    * 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 did in this circumstance.)
    pass
  if hasattr(st, 'st_flags'):
    try:
      lookup("chflags")(dst, st.st_flags, follow_symlinks=follow)
    except OSError 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)
复制文件的内容以及权限,先copyfile后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)
复制文件的内容以及文件的所有状态信息。先copyfile后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 may be 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)
递归的复制文件内容及状态信息

def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
       ignore_dangling_symlinks=False):

  names = os.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)
    dstname = os.path.join(dst, name)
    try:
      if os.path.islink(srcname):
        linkto = os.readlink(srcname)
        if symlinks:
          # 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:
          # ignore dangling symlink if the flag is on
          if not os.path.exists(linkto) and ignore_dangling_symlinks:
            continue
          # otherwise let the copy occurs. copy2 will 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, symlinks, ignore, copy_function)
      else:
        # Will raise a SpecialFileError for unsupported file types
        copy_function(srcname, dstname)
    # catch the Error from the recursive copytree so that we can
    # continue with other files
    except Error as err:
      errors.extend(err.args[0])
    except OSError as why:
      errors.append((srcname, dstname, str(why)))
  try:
    copystat(src, dst)
  except OSError as why:
    # Copying file access times may fail on Windows
    if getattr(why, 'winerror', None) is 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 -l
total 0
-rw-r--r--. 1 python python 0 May 14 19:36 hahaha
-rw-r--r--. 1 python python 0 May 14 19:36 test1
-rw-r--r--. 1 root  root  0 May 14 19:36 test2
>>> shutil.copytree('copytree_test','copytree_copy')
'copytree_copy'
[root@slyoyo python_test]# ls -l
total 12
drwxr-xr-x. 3 root  root  4096 May 14 19:36 copytree_copy
drwxr-xr-x. 3 root  root  4096 May 14 19:36 copytree_test
-rw-r--r--. 1 python python  79 May 14 05:17 test1
-rw-r--r--. 1 root  root   0 May 14 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)
递归地删除文件

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 based 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(orig_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 are forbidden, see bug #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)
递归的移动文件

def move(src, dst):

  real_dst = dst
  if os.path.isdir(dst):
    if _samefile(src, dst):
      # We might be on 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

登录后复制


10 make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0,dry_run=0, owner=None, group=None, logger=None)

压缩打包

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 is 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:
      if logger is not None:
        logger.debug("changing back to '%s'", save_cwd)
      os.chdir(save_cwd)
  return filename

登录后复制


base_name: 压缩打包后的文件名或者路径名
format: 压缩或者打包格式 "zip", "tar", "bztar"or "gztar"
root_dir : 将哪个目录或者文件打包(也就是源文件)

>>> shutil.make_archive('tarball','gztar',root_dir='copytree_test')
[root@slyoyo python_test]# ls -l
total 12
drwxr-xr-x. 3 root  root  4096 May 14 19:36 copytree_copy
drwxr-xr-x. 3 root  root  4096 May 14 19:36 copytree_test
-rw-r--r--. 1 root  root   0 May 14 21:12 tarball.tar.gz
-rw-r--r--. 1 python python  79 May 14 05:17 test1
-rw-r--r--. 1 root  root   0 May 14 19:10 test2
登录后复制

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

2小时的Python计划:一种现实的方法 2小时的Python计划:一种现实的方法 Apr 11, 2025 am 12:04 AM

2小时内可以学会Python的基本编程概念和技能。1.学习变量和数据类型,2.掌握控制流(条件语句和循环),3.理解函数的定义和使用,4.通过简单示例和代码片段快速上手Python编程。

Python:探索其主要应用程序 Python:探索其主要应用程序 Apr 10, 2025 am 09:41 AM

Python在web开发、数据科学、机器学习、自动化和脚本编写等领域有广泛应用。1)在web开发中,Django和Flask框架简化了开发过程。2)数据科学和机器学习领域,NumPy、Pandas、Scikit-learn和TensorFlow库提供了强大支持。3)自动化和脚本编写方面,Python适用于自动化测试和系统管理等任务。

Navicat查看MongoDB数据库密码的方法 Navicat查看MongoDB数据库密码的方法 Apr 08, 2025 pm 09:39 PM

直接通过 Navicat 查看 MongoDB 密码是不可能的,因为它以哈希值形式存储。取回丢失密码的方法:1. 重置密码;2. 检查配置文件(可能包含哈希值);3. 检查代码(可能硬编码密码)。

如何将 AWS Glue 爬网程序与 Amazon Athena 结合使用 如何将 AWS Glue 爬网程序与 Amazon Athena 结合使用 Apr 09, 2025 pm 03:09 PM

作为数据专业人员,您需要处理来自各种来源的大量数据。这可能会给数据管理和分析带来挑战。幸运的是,两项 AWS 服务可以提供帮助:AWS Glue 和 Amazon Athena。

redis怎么启动服务器 redis怎么启动服务器 Apr 10, 2025 pm 08:12 PM

启动 Redis 服务器的步骤包括:根据操作系统安装 Redis。通过 redis-server(Linux/macOS)或 redis-server.exe(Windows)启动 Redis 服务。使用 redis-cli ping(Linux/macOS)或 redis-cli.exe ping(Windows)命令检查服务状态。使用 Redis 客户端,如 redis-cli、Python 或 Node.js,访问服务器。

redis怎么读取队列 redis怎么读取队列 Apr 10, 2025 pm 10:12 PM

要从 Redis 读取队列,需要获取队列名称、使用 LPOP 命令读取元素,并处理空队列。具体步骤如下:获取队列名称:以 "queue:" 前缀命名,如 "queue:my-queue"。使用 LPOP 命令:从队列头部弹出元素并返回其值,如 LPOP queue:my-queue。处理空队列:如果队列为空,LPOP 返回 nil,可先检查队列是否存在再读取元素。

Redis如何查看服务器版本 Redis如何查看服务器版本 Apr 10, 2025 pm 01:27 PM

问题:如何查看 Redis 服务器版本?使用命令行工具 redis-cli --version 查看已连接服务器的版本。使用 INFO server 命令查看服务器内部版本,需解析返回信息。在集群环境下,检查每个节点的版本一致性,可使用脚本自动化检查。使用脚本自动化查看版本,例如用 Python 脚本连接并打印版本信息。

Navicat的密码安全性如何? Navicat的密码安全性如何? Apr 08, 2025 pm 09:24 PM

Navicat的密码安全性依赖于对称加密、密码强度和安全措施的结合。具体措施包括:采用SSL连接(前提是数据库服务器支持并正确配置证书)、定期更新Navicat、使用更安全的方式(如SSH隧道)、限制访问权限,最重要的是,绝不记录密码。

See all articles