zoukankan      html  css  js  c++  java
  • Python [习题] 文件操作:目录间copy 文件


    [习题] 指定一个源文件,实现copy到目标目录。
    例如把/tmp/sample1.txt 拷贝到/tmp/sample2.txt
    原文件需要有读权限(默认rt权限),目标文件需要给写(w即可)权限。

    In [8]: with open('/tmp/sample1.txt',encoding='UTF-8') as f1:
       ...:     with open('/tmp/sample2.txt','w',encoding='utf-8') as f2:
       ...:         content = f1.read()
       ...:         f2.write(content)
       ...:
    
    In [9]: ls
     C:python171025 的目录
    2017/10/26  09:00    <DIR>          .
    2017/10/26  09:00    <DIR>          ..
    2017/10/25  19:20            13,099 sample1.txt
    2017/10/26  09:01            13,099 sample2.txt
    

      

    只拷贝了文件内容,文件元信息并未拷贝。

    文件元信息是指文件的具体信息:

     14:59:24 � ⚡ � root@ihoneysec � ~ �
    #  stat optime.sh
      文件:"optime.sh"
      大小:5506      	块:16         IO 块:4096   普通文件
    设备:fd00h/64768d	Inode:33579806    硬链接:1
    权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
    最近访问:2017-10-12 17:51:21.028568171 +0800
    最近更改:2017-10-12 17:51:15.868567925 +0800
    最近改动:2017-10-12 17:51:15.868567925 +0800
    创建时间:-
    

      

    文件元信息的复制

    copyfileobj(fsrc, fdst[, length])
    文件对象的复制,fsrc和fdst是open打开的文件对象,复制内容。fdst要求可写。
    length指定了表示buffer的大小;

    copyfileobj:

    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)
    

      

    In [35]: with open('test1','r+') as f1:
        ...:     with open('test2','w') as f2:
        ...:         f1.write('abcd
    1234')   #文件指针移到末尾
        ...:         f1.flush()
        ...:         shutil.copyfileobj(f1,f2)   #此时再读 f1 内容就是空了,所以copyfileobj copy生成的文件是空
        ...:         
    
    In [36]: ll
    -rw-rw-r-- 1 python     9 10月 26 19:58 test1
    -rw-rw-r-- 1 python     0 10月 26 19:58 test2
    
    In [38]: !stat test1
      文件:"test1"
      大小:9         	块:8          IO 块:4096   普通文件
    设备:fd00h/64768d	Inode:1423520     硬链接:1
    权限:(0664/-rw-rw-r--)  Uid:( 1000/  python)   Gid:( 1000/  python)
    最近访问:2017-10-26 19:58:00.061372104 +0800
    最近更改:2017-10-26 19:58:00.061372104 +0800
    最近改动:2017-10-26 19:58:00.061372104 +0800
    创建时间:-
    
    In [39]: !stat test2
      文件:"test2"
      大小:0         	块:0          IO 块:4096   普通空文件
    设备:fd00h/64768d	Inode:1423521     硬链接:1
    权限:(0664/-rw-rw-r--)  Uid:( 1000/  python)   Gid:( 1000/  python)
    最近访问:2017-10-26 19:58:00.061372104 +0800
    最近更改:2017-10-26 19:58:00.061372104 +0800
    最近改动:2017-10-26 19:58:00.061372104 +0800
    创建时间:-
    

      

    copyfile(src, dst, *, follow_symlinks=True)
    复制文件内容,不含元数据。src、dst为文件的路径字符串
    本质上是在调用 os.symlink 和 copyfileobj ,所以不带元数据复制。

    copymode(src, dst, *, follow_symlinks=True)
    只拷贝权限

    copystat(src, dst, *, follow_symlinks=True)
    从src复制所有文件状态信息(权限,atime,mtime,flag)到dst,follow_symlinks=True默认会跟踪复制原文件,如果设置为False,仅仅复制符号链接

    copy(src, dst, *, follow_symlinks=True)
    复制文件内容、权限和部分元数据,不包括创建数据和修改实际。
    本质上调用的是copyfile和copymode:
    copyfile(src, dst, follow_symlinks=follow_symlinks)
    copymode(src, dst, follow_symlinks=follow_symlinks)

    copy2(src, dst, *, follow_symlinks=True)
    copy2比copy多了复制全部元数据,但需要平台支持。
    本质上调用的也是:
    copyfile(src, dst, follow_symlinks=follow_symlinks)
    copymode(src, dst, follow_symlinks=follow_symlinks)
    还有一点和copy的区别是copy函数检查如果源和目标都是相同的文件,会抛异常SameFileError ,而copy2不会。


    copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,ignore_dangling_symlinks=False)
    递归复制目录。默认使用copy2,也就是带更多的元数据复制。
    src、dst必须是目录,src必须存在,dst必须不存在
    ignore=func,提供一个callable(src,names) -> ignored_names。提供一个函数,它会被调用。src是源目录,names是os.listdir(src)的结果,就是列出src中的文件名,返回值是要被过滤的文件名的set类型数据。

    def ignore(src,names):
        ig = filter(lambda x:x.startwith('a'),names) #忽略a
    	return set(ig)
    shutil.copytree('/var/log/nginx','/tmp/ng_log',ignore=ignore)
    

      

    rmtree(path, ignore_errors=False, onerror=None)
    递归删除。如同rm -rf 一样危险,建议使用rm命令一定不要加-rf,再次考虑清楚再确定使用-rf。
    它不是原子操作,有可能删除错误,就会中断,已经删除的就删除了。
    ignore_error为true,忽略错误。当为False或者omitted时onerror生效。
    onerror为callable,接受函数function、path和execinfo。

    shutil.rmtree('/tmp/ng_log') #类似 rm -rf

    move 移动
    move(src, dst, copy_function=copy2)
    递归移动文件、目录到目标,返回目标。
    本身使用的时os.rename方法。
    如果不支持rename,再判断如果是链接文件,则创建链接原文件到dst,然后删除src。
    如果是目录则调用copytree递归复制到dst,再删除src目录,如果都不是,都调用copy2复制,在调用unlink删除(类remove)。
    os.rename('/tmp/ng_log/nginx.log','/tmp/ng_log/nginx.log.bak20171026')
    os.rename('php-fpm.log','/tmp/php-fpm.log')

  • 相关阅读:
    Direct3D 光照和材质
    UGUI 过渡动画插件,模仿NGUI的Tween (转载)
    Unity 功夫猫
    LinkedList和List在三种简单算法中效率比较
    学习Modern UI for WPF
    H3 BPM Sheet表单 NTKO功能使用说明
    H3 BPM MVC表单SheetOffice控件使用分享
    H3 BPM初次安装常见错误详解5-7
    吕学敏:全面、细致功能锻造灵活审批
    华陆工程——业务流程管理方案
  • 原文地址:https://www.cnblogs.com/i-honey/p/7735709.html
Copyright © 2011-2022 走看看