自己实现一个复制文件的函数

实现一个拷贝文件的功能,提醒:要考虑超大文件问题,如:依次读取1024字节,循环读取

初版代码,只能把文件复制到文件

def diy_copy(src_file_path,destination_file_path): # 复制文件。源文件路径,目标文件路径
    f_read=open(src_file_path,'r',encoding='utf-8') # 读取源文件
    string=f_read.read(1024) # 如果是仅1行的超大文件,一次读取一部分

    f_write=open(destination_file_path,'w',encoding='utf-8') # 写入目标文件
    while(string): # 只要读取的内容不为空就持续写入并读取后面的
        f_write.write(string)
        string=f_read.read(1024)
    f_write.close()

    f_read.close()
diy_copy('','')

完善优化后的第二版,把文件/目录复制到文件/目录

先发流程图,是写完第二版代码后画的,如果有错还请指出。只是解决这个问题的思想,不一定和代码执行流程一模一样。第一次用visio,还不太会用。

import os
from os import path
def copy_single_file(src_file_path,destination_file_path): # 从文件复制到文件、从文件复制到目录
    if path.isdir(destination_file_path): # 如果第二个参数是目录
        src_file_name=path.basename(src_file_path) # 提取源文件名,含扩展名
        destination_file_path=path.join(destination_file_path,src_file_name) # 将目录与文件名拼接,生成最终的第二个参数

    f_read=open(src_file_path,'r',encoding='utf-8') # 读取源文件
    string=f_read.read(1024) # 如果是仅1行的超大文件,一次读取一部分

    f_write=open(destination_file_path,'w',encoding='utf-8') # 写入目标文件
    while(string): # 只要读取的内容不为空就持续写入并读取后面的
        f_write.write(string)
        string=f_read.read(1024)
    f_write.close()

    f_read.close()
def dir_or_file(destination_file_path): # True说明目标地址是文件,False是目录
    '''
    判断目标地址是文件还是目录的思路:
    如果名字里有'.',且后面是纯字母(忽略m3u8,写完才想起这个,不过它是.ts),那它是文件;如果后面不是纯字母,那它是目录(如版本号1.1.0).
    如果名字里没有'.',那它是目录(忽略无扩展名的文件,这里把无扩展名的作为目录).
    可能可以直接用正则判断----------学过正则后补充这个函数的正则写法--------------------------
    还可以用rsplit('.',1),如果返回的列表长度为1,则是目录;如果长度不为1,且列表最后一个元素是纯字母,则它是文件,否则是目录
    '''
    '''这个函数也可以这么写,因path.basename()底层调用path.split()
    temp_tuple=path.split('a/b/c/d/')
    if '.' in temp_tuple[-1]:
        temp_list=temp_tuple[-1].split('.')
        if temp_list[-1].isalpha():
            return True
        else:
            return False
    else:
        return False
    '''
    name = path.basename(destination_file_path)
    if '.' in name:
        name_split = name.split('.')
        if name_split[-1].isalpha():
            return True
        else:
            return False
    else:
        return False
def diy_copy(src_file_path,destination_file_path):
    if path.abspath(src_file_path)==path.abspath(destination_file_path): # 第一个参数写绝对路径,终端运行不报错;写相对路径,终端运行报错,pycharm不报错
        print('源文件与目标地址相同,无法复制')
        return
    if path.isdir(src_file_path) and dir_or_file(destination_file_path): # 后者返回True说明后者的参数是一个文件
        print('源文件是目录,目标地址是文件,无法复制')
        return
    if not path.exists(destination_file_path): # 上面都是不能复制的,不用创建原来不存在的目录;下面都是能复制的,需要先创建原来不存在的目录,后面才能用path.isdir()判断
        if dir_or_file(destination_file_path): # 目标地址是文件.这里先不用创建地址中间不存在的目录,copy_single_file()会创建
            copy_single_file(src_file_path, destination_file_path)
        elif not dir_or_file(destination_file_path): # 目标地址是目录
            os.makedirs(destination_file_path)
    if path.isdir(src_file_path) and path.isdir(destination_file_path): # 把目录复制到目录
        filelist=os.listdir(src_file_path)
        for i in filelist: # 要定义新变量存放新路径,如果用新路径覆盖src_file_path和destination_file_path,多层嵌套的目录结构递归时会报错
            temp_src_file_path=path.join(src_file_path,i)
            temp_destination_file_path=path.join(destination_file_path,i)
            if path.isdir(temp_src_file_path): # 递归复制目录
                diy_copy(temp_src_file_path,temp_destination_file_path)
            else:
                copy_single_file(temp_src_file_path,temp_destination_file_path)
    else: # 从文件复制到文件、从文件复制到目录
        copy_single_file(src_file_path,destination_file_path)
diy_copy('','') # 无论目标目录是否已存在,及无论源路径是目录时最后一个符号是否是/.支持测试从文件到文件、从文件到目录、从目录到文件、从目录到目录

# diy_copy('z:/a/新建文本文档.txt','z:/1.txt') # 从文件复制到文件 OK
# diy_copy('z:/a/新建文本文档.txt','z:/新建文本文档.txt') # 从文件复制到文件 OK
# diy_copy('z:/a/新建文本文档.txt','z:/b/') # 从文件复制到目录 OK
# diy_copy('z:/a/新建文本文档.txt','z:/b') # 从文件复制到目录 OK
# diy_copy('z:/a','z:/b') # 从目录复制到目录 OK
# diy_copy('z:/a','z:/b/') # 从目录复制到目录 OK
# diy_copy('z:/a','z:/新建文本文档.txt') # 从目录复制到文件 正常报错
# diy_copy('z:/a/新建文本文档.txt','z:/a/新建文本文档.txt') # 源与目的的路径相同 正常报错

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值