Python copies the file code implementation

  • 2020-04-02 13:17:05
  • OfStack

The main function is implemented in the copyFiles() function, as follows:


def copyFiles(src, dst):
    srcFiles = os.listdir(src)
    dstFiles = dict(map(lambda x:[x, ''], os.listdir(dst)))
    filesCopiedNum = 0

    #  Copy each file in the source folder if it does not exist in the destination folder 
    for file in srcFiles:
        src_path = os.path.join(src, file)
        dst_path = os.path.join(dst, file)
        #  If the source path is a folder, if it exists in the target folder, then recursively call this function; Otherwise create first and then recurse. 
        if os.path.isdir(src_path):
            if not os.path.isdir(dst_path):
                os.makedirs(dst_path)  
            filesCopiedNum += copyFiles(src_path, dst_path)
        #  If the source path is a file, duplicate if not, otherwise no operation. 
        elif os.path.isfile(src_path):                
            if not dstFiles.has_key(file):
                shutil.copyfile(src_path, dst_path)
                filesCopiedNum += 1

    return filesCopiedNum

Here I first use the os.listdir() function to traverse the source folder SRC and the target folder DST to get two lists of files, but since I need to override the operation, I need to query in the DST file list. Since the query efficiency of the list is not high, and the dictionary is a hash table, the query efficiency is high, so I converted the target file list into a dictionary with only keys and no values:


dstFiles = dict(map(lambda x:[x, ''], os.listdir(dst)))

Then I walk through the list of source files, and if the path is a folder, first determine whether the folder exists in the target path, if not, then create a new path. This function is then called recursively. A more efficient method is to call the shutil.copytree() function when it doesn't exist, but because you need to count the number of copies, you don't call it.

If the path is a file, first determine whether the file exists in the target folder. If not, copy.

Since this script was written primarily to sync your phone's photo album to your PC, it's only a matter of determining the file name. To determine the same file with a different name, you can continue to determine the md5 value, which I won't repeat here.

The complete code is as follows:


#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#  Enter two folders a and b Path, a Copy in the file b And count the number of files copied. Repetitive do not handle. 
import os
import shutil
def copyFiles(src, dst):
    srcFiles = os.listdir(src)
    dstFiles = dict(map(lambda x:[x, ''], os.listdir(dst)))
    filesCopiedNum = 0

    #  Copy each file in the source folder if it does not exist in the destination folder 
    for file in srcFiles:
        src_path = os.path.join(src, file)
        dst_path = os.path.join(dst, file)
        #  If the source path is a folder, if it exists in the target folder, then recursively call this function; Otherwise create first and then recurse. 
        if os.path.isdir(src_path):
            if not os.path.isdir(dst_path):
                os.makedirs(dst_path)  
            filesCopiedNum += copyFiles(src_path, dst_path)
        #  If the source path is a file, duplicate if not, otherwise no operation. 
        elif os.path.isfile(src_path):                
            if not dstFiles.has_key(file):
                shutil.copyfile(src_path, dst_path)
                filesCopiedNum += 1

    return filesCopiedNum
def test():
    src_dir = os.path.abspath(raw_input('Please enter the source path: '))
    if not os.path.isdir(src_dir):
        print 'Error: source folder does not exist!'
        return 0

    dst_dir = os.path.abspath(raw_input('Please enter the destination path: '))
    if os.path.isdir(dst_dir):
        num = copyFiles(src_dir, dst_dir)
    else:
        print 'Destination folder does not exist, a new one will be created.'
        os.makedirs(dst_dir)
        num = copyFiles(src_dir, dst_dir)
    print 'Copy complete:', num, 'files copied.'
if __name__ == '__main__':
    test()


Related articles: