如何使用Paramiko getfo从SFTP服务器下载文件到内存进行处理
How to use Paramiko getfo to download file from SFTP server to memory to process it
我正在尝试使用 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: File is not open for reading
我假设 fl
我需要某种缓冲区或文件之类的对象,因为打开需要一个文件。我对所有这些都比较陌生,所以如果有人能提供帮助,我会很高兴。
仍然允许您使用进度回调的简单解决方案是:
使用BytesIO
file-like object将下载的文件存储到内存中;
下载后必须先将文件指针找回文件开头,然后才能开始阅读。
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
调用,参考:
.
如果不需要进度监控,简单的代码如下:
with sftp.open(file_name, "rb") as fl:
fl.prefetch()
df = pd.read_csv(fl, sep=' ')
我最后做的是一个简单的版本,不幸的是没有进度回调,我还需要 rb
阅读:
with sftp.open(file_name, 'rb') as fl:
df = pd.read_csv(fl, sep=' ')
无论如何,马丁的回答正是我要找的!
我正在尝试使用 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: File is not open for reading
我假设 fl
我需要某种缓冲区或文件之类的对象,因为打开需要一个文件。我对所有这些都比较陌生,所以如果有人能提供帮助,我会很高兴。
仍然允许您使用进度回调的简单解决方案是:
使用
BytesIO
file-like object将下载的文件存储到内存中;下载后必须先将文件指针找回文件开头,然后才能开始阅读。
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
调用,参考:
如果不需要进度监控,简单的代码如下:
with sftp.open(file_name, "rb") as fl:
fl.prefetch()
df = pd.read_csv(fl, sep=' ')
我最后做的是一个简单的版本,不幸的是没有进度回调,我还需要 rb
阅读:
with sftp.open(file_name, 'rb') as fl:
df = pd.read_csv(fl, sep=' ')
无论如何,马丁的回答正是我要找的!