shutil复制文件却丢失数据:Python代码运行异常排查
嘿,我来帮你捋捋这个问题——文件能顺利复制到目标目录,但偶尔会出现CSV空数据的情况,结合你给出的代码片段,大概率是写入逻辑没走完就触发复制,或者写入时数据没正确刷入磁盘导致的,下面给你拆解几个最可能的原因和对应的解决办法:
1. 文件写入未正确关闭/刷新缓冲区
如果你的CSV写入代码没用到with语句,或者写完后没手动关闭文件,系统的缓冲区可能还没把数据真正写到磁盘上,这时候去复制文件,拿到的自然是空的。比如你要是这么写:
writer = csv.writer(open(self.srcfile % self.i, 'w')) writer.writerow(...) # 没写close()就直接复制
这种情况很容易出问题,因为文件句柄没关闭的话,数据可能还停留在内存里,没落地到磁盘。
解决办法:
一定要用with语句管理文件,它会自动帮你关闭文件并刷新缓冲区,稳得很:
with open(self.srcfile % self.i, 'w', newline='') as f: writer = csv.writer(f) writer.writerow(['表头1', '表头2', '表头3']) # 先写好表头 # 这里写你的数据写入逻辑
2. 无数据时完全未操作文件
如果你的代码只有在有数据的时候才写入文件,没数据就啥也不做,那生成的CSV就是空文件——但因为初始化流程可能创建了空文件(或者复制操作直接生成了空文件),就会出现"文件存在但无内容"的情况。
解决办法:
哪怕没数据,至少把表头写上!这样文件就不会是空的,比如:
with open(self.srcfile % self.i, 'w', newline='') as f: writer = csv.writer(f) writer.writerow(['姓名', '邮箱', '联系电话']) # 固定写入表头 if 有数据需要写入: writer.writerows(你的数据列表)
3. 复制操作跑在了写入前面
这是最容易踩的坑!要是你先执行了复制操作,再去写数据,那复制的肯定是空文件啊!比如你的流程是:
exporter = myExporter() shutil.copy(生成的文件名, 目标目录) # 然后才开始写数据
这顺序完全反了好嘛!
解决办法:
一定要等所有写入逻辑彻底完成(也就是with块结束,文件已经安全关闭),再调用shutil去复制文件。
4. 文件名生成的小隐患
看你初始化里的文件名生成逻辑:
while os.path.exists(self.srcfile % self.i): self.i += 1
虽然概率不高,但万一有其他进程也在生成同名文件,或者代码里不小心修改了self.i,可能导致你写入的文件和复制的不是同一个?建议加个日志确认下:
current_file = self.srcfile % self.i print(f"正在写入文件: {current_file}") # 写入逻辑 print(f"正在复制文件: {current_file} 到 {self.folderdes}") shutil.copy(current_file, self.folderdes)
这样能快速排查是不是文件名不匹配的问题。
5. 写入时异常未被捕获
要是写入过程中遇到了错误(比如数据格式不对,没法写入CSV),但代码没捕获异常,写入就会中途断掉,文件可能就空了或者只有半拉内容。
解决办法:
给写入逻辑加个异常捕获,顺便打个日志,方便排查问题:
try: with open(current_file, 'w', newline='') as f: writer = csv.writer(f) writer.writerow(表头) for row in 数据列表: writer.writerow(row) except Exception as e: print(f"写入CSV出错啦: {str(e)}") # 也可以在这里把空文件删掉,避免复制空文件到目标目录
总结下,先优先检查前三个问题,尤其是有没有用with写文件、复制顺序对不对,这俩是最常见的诱因~
内容的提问来源于stack exchange,提问作者user6393083

