Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用Paramiko getfo将文件从SFTP服务器下载到内存中进行处理_Python_Pandas_Io_Sftp_Paramiko - Fatal编程技术网

Python 如何使用Paramiko getfo将文件从SFTP服务器下载到内存中进行处理

Python 如何使用Paramiko getfo将文件从SFTP服务器下载到内存中进行处理,python,pandas,io,sftp,paramiko,Python,Pandas,Io,Sftp,Paramiko,我正在尝试使用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.ge

我正在尝试使用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需要一个文件。我对所有这些都比较陌生,因此如果有人能帮助我,我将非常高兴。

一个仍然允许您使用进度回调的简单解决方案是:

  • 用于将下载的文件存储到内存中

  • 下载文件后,在开始读取之前,必须将文件指针搜索回文件开始

    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
调用,请参阅:

.

我最后做的只是一个简单的版本,不幸的是没有进度回调,我还需要阅读
rb

with sftp.open(file_name, 'rb') as fl:
        df = pd.read_csv(fl, sep=' ')

不管怎样,马丁的答案正是我想要的

那正是我要找的!同时,我还找到了另一个解决方案,它不如我不能通过回调来报告进度(见下面的答案)。非常感谢。