• shutil模块


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

     

    常用的方法:

    1.对象拷贝(将1个文件的内容拷贝到另一个文件)

    shutil.copyfileobj(fsrc,fdst,[,length])

    源代码——

    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)

    通过源代码可以看到,这个方法其实就是通过循环读取文件内容,一次读取指定的长度(单位KB)再把读取到的内容写入目标文件。

    演示:

    把/etc/passwd拷贝到当前目录,执行如下代码段

    #!/usr/bin/env python3

     

    import shutil

     

    shutil.copyfileobj(open('passwd','r'),open('new_passwd','w'))

    执行结果:

    alben@Python:~/Python_scripts$ ./file_obj.py

    alben@Python:~/Python_scripts$ ls | grep passwd

    new_passwd

    passwd

    alben@Python:~/Python_scripts$ diff passwd new_passwd

    通过shell的diff比较文件,没有任何输出,说明文件内容完全一致。

     

    2,文件拷贝

    shutil.copyfile(src,dst)

    源代码——

    def copyfile(src, dst):

        """Copy data from src to dst"""

        if _samefile(src, dst):

            raise Error("`%s` and `%s` are the same file" % (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)

     

        with open(src, 'rb') as fsrc:

            with open(dst, 'wb') as fdst:

                copyfileobj(fsrc, fdst)

    在源代码中,进行了文件比较,异常处理(防止文件不存在或者文件是设备文件,套接字文件等出现的异常)

    拷贝的过程其实与copyfileobj()差不多。。。

    演示:

    把/etc/fstab文件拷贝到当前目录

    在python解释器执行代码:

    >>> import shutil

    >>> shutil.copyfile('fstab','new_fstab')

    'new_fstab'

    在shell中比较文件内容:

    alben@Python:~/Python_scripts$ diff fstab new_fstab

    alben@Python:~/Python_scripts$

    完全一致!

    但是,拷贝过来的文件权限是根据当前用户的默认权限来设置的,所以根据需要还得拷贝权限

     

    3,拷贝权限

    shutil.copymode(src,dst)

    源代码:

    def copymode(src, dst):

        """Copy mode bits from src to dst"""

        if hasattr(os, 'chmod'):

            st = os.stat(src)

            mode = stat.S_IMODE(st.st_mode)

            os.chmod(dst, mode)

    源码解析:

    在这个”方法“中,需要借助两个模块中的其他“方法”!

    •  os模块
    •  stat模块

    os.stat(src) 用于获取文件属性,我们可以测试在linux中对一个文件执行os.stat()方法

    >>> a = os.stat('passwd')

    >>> a

    os.stat_result(st_mode=33188, st_ino=2505906, st_dev=2049, st_nlink=1, st_uid=1000, st_gid=1000, st_size=2523, st_atime=1496332301, st_mtime=1496332220, st_ctime=1496332220)

    能够获取的属性,包括(mode,inode,times,gid,uid,size)

    stat.S_IMODE(st.st_mode)

    把os.stat()的结果中st_mode转换成unix 的模式表示方法

    >>> stat.S_IMODE(a.st_mode)

    420(其实这里的420不是shell中理解的那个420,具体是啥暂时未知)

    演示:

    alben@Python:~/Python_scripts$ ll a b

    -rwxrwxrwx  1 alben alben    0 6月   2 00:36 a*

    -rw-rw-r--  1 alben alben    0 6月   2 00:37 b

     

    >>> import shutil

    >>> shutil.copymode('a', 'b')

    >>>

    >>> exit()

    alben@Python:~/Python_scripts$ ll a b

    -rwxrwxrwx 1 alben alben 0 6月   2 00:36 a*

    -rwxrwxrwx 1 alben alben 0 6月   2 00:37 b*

     

    4,拷贝文件同时复制权限

    shutil.copy(src,dst)

    源代码:

    def copy(src, dst):

        """Copy data and mode bits ("cp src dst").

     

        The destination may be a directory.

     

        """

        if os.path.isdir(dst):

            dst = os.path.join(dst, os.path.basename(src))

        copyfile(src, dst)

        copymode(src, dst)

    ^_^,其实就是调用了copyfile()和copymode()

    演示:

    alben@Python:~/Python_scripts$ ll a

    -rwxr-xr-x 1 root root 0 6月   2 17:27 a*

    alben@Python:~/Python_scripts$ python3

    Python 3.5.3 (default, Jan 19 2017, 14:11:04)

    [GCC 6.3.0 20170118] on linux

    Type "help", "copyright", "credits" or "license" for more information.

    >>> import shutil

    >>> shutil.copy('a','b')

    'b'

    >>> exit()

    alben@Python:~/Python_scripts$ ll a b

    -rwxr-xr-x 1 root  root  0 6月   2 17:27 a*

    -rwxr-xr-x 1 alben alben 0 6月   2 17:36 b*

    查看文件的状态:

    stat 命令,可以发现拷贝后的新文件与源文件的ctime,mtime是不同的,如果要想这两个时间也拷贝,就需要copystat方法了

     

    4,拷贝状态

    shutil.copystat(src,dst)

    源代码:

    def copystat(src, dst):

        """Copy all stat info (mode bits, atime, mtime, flags) from src to dst"""

        st = os.stat(src)

        mode = stat.S_IMODE(st.st_mode)

        if hasattr(os, 'utime'):

            os.utime(dst, (st.st_atime, st.st_mtime))

        if hasattr(os, 'chmod'):

            os.chmod(dst, mode)

        if hasattr(os, 'chflags') and hasattr(st, 'st_flags'):

            try:

                os.chflags(dst, st.st_flags)

            except OSError as why:

                if (not hasattr(errno, 'EOPNOTSUPP') or

                    why.errno != errno.EOPNOTSUPP):

                    raise

    拷贝文件的所有状态

     

    5,移动文件

    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.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)

     

    拷贝文件,如果在同一个路径下,就是rename重命名

  • 相关阅读:
    C++学习笔记27,虚函数作品
    HDU
    POJ 2524 Ubiquitous Religions
    HDU-3839-Ancient Messages(DFS)
    thinkphp 删除所有缓存 Rumtime 以及 Html 静态缓存
    [AngularJS] Design Pattern: Simple Mediator
    [Javascript] Add a browser build to an npm module
    [Angular 2] ngrx/store
    [Typescript] Introduction to Generics in Typescript
    [AngularJS] angular-md-table for Angular material design
  • 原文地址:https://www.cnblogs.com/alben-cisco/p/6935717.html
Copyright © 2020-2023  润新知