10m*_*mjg 6 python shutil file-copying
我经常错过我尝试使用shutil copyfile复制的文件的最后几个kb.
我做了一些研究,确实看到有人在这里询问类似的东西: python shutil复制函数缺少最后几行
但我正在使用copyfile,它似乎使用了with语句......
with open(src, 'rb') as fsrc:
with open(dst, 'wb') as fdst:
copyfileobj(fsrc, fdst)
Run Code Online (Sandbox Code Playgroud)
所以我很困惑,更多的用户没有这个问题,如果它确实是某种缓冲问题 - 我会认为它更为人所知.
我非常简单地调用copyfile,不要认为我可能做错了什么,基本上按照我认为的标准方式做:
copyfile(target_file_name,dest_file_name)
Run Code Online (Sandbox Code Playgroud)
然而,我每次都错过了最后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)
Run Code Online (Sandbox Code Playgroud)
所以我不知所措,但我想我即将学习关于冲洗,缓冲或使用声明的内容,或者......帮助!谢谢
对Anand:Anand,我避免提及那些东西bc我觉得这不是问题,但是因为你问...执行摘要是我从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
Run Code Online (Sandbox Code Playgroud)
这里的问题很可能是,在执行该行时 -
ftp.retrbinary('RETR %s' % filename, fhandle.write)
Run Code Online (Sandbox Code Playgroud)
这是使用该fhandle.write()函数将数据从 ftp 服务器写入文件(名称为 - target_file_name),但是当您调用 - 时,shutil.copyfile缓冲区fhandle尚未完全刷新,因此在复制时会丢失一些数据文件。
为了确保不会发生这种情况,您可以将copyfile逻辑移出withfor 块fhandle。
或者您可以fhandle.flush()在复制文件之前调用刷新缓冲区。
我相信最好关闭文件(将逻辑移出块with)。例子 -
for filename in ftp.nlst(filematch):
target_file_name = os.path.basename(filename)
with open(target_file_name ,'wb') as fhandle:
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
Run Code Online (Sandbox Code Playgroud)