python - 如何使用 Paramiko getfo 将文件从 SFTP 服务器下载到内存进行处理
问题描述
我正在尝试使用 Paramiko 从 SFTP 下载 CSV 文件(内存中)并将其导入 pandas 数据帧。
transport = paramiko.Transport((server, 22))
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)
with open(file_name, 'wb') as fl:
sftp.getfo(file_name, fl, callback=printTotals)
df = pd.read_csv(fl, sep=' ')
下面的代码失败了,告诉我:
OSError:文件未打开以供读取
我假设我需要某种缓冲区或类似对象的文件fl
,因为 open 需要一个文件。我对所有这些都比较陌生,所以如果有人可以提供帮助,我会很高兴。
解决方案
一个仍然允许您使用进度回调的简单解决方案是:
使用
BytesIO
类文件对象将下载的文件存储到内存中;在下载文件后,您必须在开始阅读文件之前将文件指针返回到文件开头。
with io.BytesIO() as fl: sftp.getfo(file_name, fl, callback=printTotals) fl.seek(0) df = pd.read_csv(fl, sep=' ')
尽管使用此解决方案,您最终会将文件加载到内存中两次。
更好的解决方案是实现一个自定义的类文件对象。它甚至允许您同时下载和解析文件。
class FileWithProgress:
def __init__(self, fl):
self.fl = fl
self.size = fl.stat().st_size
self.p = 0
def read(self, blocksize):
r = self.fl.read(blocksize)
self.p += len(r)
print(str(self.p) + " of " + str(self.size))
return r
并像这样使用它:
with sftp.open(file_name, "rb") as fl:
fl.prefetch()
df = pd.read_csv(FileWithProgress(fl), sep=' ')
SFTPFile.prefetch
调用参考: Reading file opens with Python Paramiko
SFTPClient.open method is slow。
如果你不需要进度监控,像这样的简单代码就可以了:
with sftp.open(file_name, "rb") as fl:
fl.prefetch()
df = pd.read_csv(fl, sep=' ')
推荐阅读
- xamarin.forms - Xamarin 表单全球化
- razor - 将错误的模型传递给部分
- javascript - Express.js:如何在不使用 Multer 创建新路由的情况下将 req 对象传递给中间件
- c# - 接收列表
C#中的url参数中的参数 - machine-learning - 当数据的形状为 (x,y,z) 时如何进行聚类?
- javascript - 如何在 MarkLogic 中将行插入 JSON 文档 [更新]
- c# - RecyclableMemoryStreamManager 作为 Singleton
- python - 从 pandas 数据框中的变量中提取数值
- r - R:从钻石数据集中的每个切工质量中抽取 100 个随机价格?
- ruby-on-rails - 为什么升级到 Ruby 2.6 后平均可用内存插槽会显着增加?