如何用Paramiko getfo从SFTP下载CSV到内存并导入Pandas?报错求解
解决Paramiko SFTP下载CSV到内存并导入Pandas DataFrame的问题
这个问题我之前也踩过坑!你遇到的OSError: File is not open for reading错误主要有两个核心原因:
- 你用
open(file_name, 'wb')打开的是本地磁盘文件,而且是只写模式,但pd.read_csv需要的是可读的文件对象; - 当
with块结束时,这个本地文件会被自动关闭,后续再读取自然会触发报错。
更关键的是你想要在内存中处理,完全不需要写入本地文件,用io.BytesIO这个内存类文件对象就能完美解决——它就像一个存在内存里的虚拟文件,不需要磁盘IO操作,效率还更高。
修正后的完整代码
import paramiko import pandas as pd from io import BytesIO # 初始化SFTP连接 transport = paramiko.Transport((server, 22)) transport.connect(username=username, password=password) sftp = paramiko.SFTPClient.from_transport(transport) # 用BytesIO在内存中暂存CSV内容 with BytesIO() as memory_file: # 将SFTP上的文件下载到内存对象中 sftp.getfo(file_name, memory_file, callback=printTotals) # 重点:把文件指针移到流的开头! # getfo写完后指针停在流的末尾,Pandas读取时会从当前位置开始,必须移到起始位置才能读到内容 memory_file.seek(0) # 读取内存中的CSV到DataFrame,sep参数根据你的实际分隔符调整 df = pd.read_csv(memory_file, sep=' ') # 记得关闭连接释放资源 sftp.close() transport.close()
关键细节说明
BytesIO是Python标准库io模块里的类,专门用来在内存中处理二进制流,完全替代本地文件的作用;memory_file.seek(0)绝对不能忘!写入完成后文件指针停在流的最后,Pandas读取时会从这个位置开始,自然读不到内容,必须把指针移到起始位置;- 如果你的CSV文件有特定编码(比如utf-8、gbk),可以在
pd.read_csv里加上encoding参数,比如encoding='utf-8'; - 确保你已经定义了
printTotals回调函数(用来显示下载进度),如果不需要进度提示可以直接去掉这个参数。
内容的提问来源于stack exchange,提问作者lukas_o
相关产品推荐
相关产品推荐

