Python shutil copyfile缺少最后几行

2024-10-06 11:25:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我经常会丢失使用shutil copyfile复制的文件的最后几kb。在

我做了一些调查,确实看到有人在问类似的问题: python shutil copy function missing last few lines

但我使用的是copyfile,它似乎确实使用了with语句。。。在

with open(src, 'rb') as fsrc:
    with open(dst, 'wb') as fdst:
        copyfileobj(fsrc, fdst)

因此,我很困惑,更多的用户没有这个问题,如果这确实是某种缓冲问题-我认为这将是更众所周知的。在

我打电话给copyfile非常简单,不要认为我可能做错了什么,基本上是按照我认为的标准方式来做:

^{pr2}$

但我每次都会丢失最后4kb左右的文件。在

我也没有碰过在shutil中调用的copyfile函数,它是。。。在

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)

所以我很困惑,但我想我将要学习一些关于刷新、缓冲或with语句的知识,或者。。。救命啊!谢谢


致Anand: 阿南德,我避免提到那件事,我觉得这不是问题所在,但既然你问了。。。执行摘要是,我从FTP抓取一个文件,检查该文件是否与上次保存副本时不同,如果不同,则下载该文件并保存一个副本。这是一个迂回的意大利面代码,我猜是在我还是一个真正的实用主义编程新手的时候写的。它看起来像:

for filename in ftp.nlst(filematch):
    target_file_name = os.path.basename(filename)
    with open(target_file_name ,'wb') as fhandle:
    try:
        ftp.retrbinary('RETR %s' % filename, fhandle.write)
        the_files.append(target_file_name)
        mtime = modification_date(target_file_name)
        mtime_str_for_file = str(mtime)[0:10] + str(mtime)[11:13] + str(mtime)[14:16]    + str(mtime)[17:19] + str(mtime)[20:28]#2014-12-11 15:08:00.338415.
        sorted_xml_files = [file for file in glob.glob(os.path.join('\\\\Storage\\shared\\', '*.xml'))]
        sorted_xml_files.sort(key=os.path.getmtime)
        last_file = sorted_xml_files[-1]
        file_is_the_same = filecmp.cmp(target_file_name, last_file)
        if not file_is_the_same:
            print 'File changed!'
            copyfile(target_file_name, '\\\\Storage\\shared\\'+'datebreaks'+mtime_str_for_file+'.xml') 
        else:
            print 'File '+ last_file +' hasn\'t changed, doin nothin'
            continue

Tags: 文件nametargetforwithfilesxmlfile
3条回答

This似乎有更好的方法来执行嵌套withs

with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst:
        copyfileobj(fsrc, fdst)

我想试试这样的。我远不是专家,希望有更渊博的人能给我一些见解。我最好的想法是,内部的with比外部的先关闭。在

您试图复制一个未关闭的文件。这就是为什么缓冲区没有被刷新。将copyfileobj移出with块,以允许fhandle关闭。在

执行:

with open(target_file_name ,'wb') as fhandle:
    ftp.retrbinary('RETR %s' % filename, fhandle.write)

# and here the rest of your code
# so fhandle is closed, and file is stored completely on the disk

这里的问题很可能是,当执行行-

ftp.retrbinary('RETR %s' % filename, fhandle.write)

这是使用fhandle.write()函数将数据从ftp服务器写入文件(名称为-target_file_name),但在调用-shutil.copyfile时,fhandle的缓冲区尚未完全刷新,因此在复制文件时丢失了一些数据。在

为了确保不会发生这种情况,您可以将copyfile逻辑移出with块中的fhandle。在

或者,在复制文件之前,可以调用fhandle.flush()刷新缓冲区。在

我相信最好关闭文件(将逻辑移出with块)。示例-

^{pr2}$

相关问题 更多 >