从FTP python读取缓冲区中的文件
我正在尝试从FTP服务器读取文件。该文件是从FTP python读取缓冲区中的文件,python,ftp,stream,ftplib,Python,Ftp,Stream,Ftplib,我正在尝试从FTP服务器读取文件。该文件是.gz文件。我想知道在套接字打开时是否可以对此文件执行操作。我试着按照上面两个StackOverflow问题中提到的内容去做,但没有成功 我知道如何在下载的文件上提取数据/工作,但我不确定是否可以在运行中提取数据/工作。是否有方法连接到站点,在缓冲区中获取数据,可能进行一些数据提取并退出 尝试StringIO时,我遇到了错误: >>> from ftplib import FTP >>> from StringIO i
.gz
文件。我想知道在套接字打开时是否可以对此文件执行操作。我试着按照上面两个StackOverflow问题中提到的内容去做,但没有成功
我知道如何在下载的文件上提取数据/工作,但我不确定是否可以在运行中提取数据/工作。是否有方法连接到站点,在缓冲区中获取数据,可能进行一些数据提取并退出
尝试StringIO时,我遇到了错误:
>>> from ftplib import FTP
>>> from StringIO import StringIO
>>> ftp = FTP('ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz')
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
ftp = FTP('ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz')
File "C:\Python27\lib\ftplib.py", line 117, in __init__
self.connect(host)
File "C:\Python27\lib\ftplib.py", line 132, in connect
self.sock = socket.create_connection((self.host, self.port), self.timeout)
File "C:\Python27\lib\socket.py", line 553, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
gaierror: [Errno 11004] getaddrinfo failed
>>从ftplib导入FTP
>>>从StringIO导入StringIO
>>>ftp=ftp('ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz')
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ftp=ftp('ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz')
文件“C:\Python27\lib\ftplib.py”,第117行,在_init中__
self.connect(主机)
文件“C:\Python27\lib\ftplib.py”,第132行,在connect中
self.sock=socket.create_连接((self.host,self.port),self.timeout)
文件“C:\Python27\lib\socket.py”,第553行,位于create\u connection中
对于getaddrinfo(主机、端口、0、SOCK_流)中的res:
gaierror:[Errno 11004]getaddrinfo失败
我只需要知道如何将数据放入某个变量中并在其上循环,直到读取FTP中的文件
我感谢你的时间和帮助。谢谢 我可以想出两种简单的方法来使用FTP下载文件并将其存储在本地:
ftplib
:
from ftplib import FTP
ftp = FTP('ftp.ncbi.nlm.nih.gov')
ftp.login()
ftp.cwd('pub/pmc')
ftp.retrbinary('RETR PMC-ids.csv.gz', open('PMC-ids.csv.gz', 'wb').write)
ftp.quit()
urllib
from urllib import urlretrieve
urlretrieve("ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz", "PMC-ids.csv.gz")
urllib2
:
from urllib2 import urlopen
u = urlopen("ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/readme.txt")
for line in u:
print line
逐行打印您的文件。这是不可能的。要在服务器上处理数据,您需要具有某种执行权限,无论是针对要发送的shell脚本还是SQL access FTP是纯文件传输,不允许执行。您需要启用SSH访问,将数据加载到数据库中并通过查询访问该数据库,或者使用
urllib
下载文件,然后在本地对其进行处理,如下所示:
import urllib
handle = urllib.urlopen('ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/PMC-ids.csv.gz')
# Use data, maybe: buffer = handle.read()
特别是,我认为第三个是唯一的零努力解决方案。确保首先登录到ftp服务器。之后,使用
retrbinary
以二进制模式提取文件。它对文件的每个块使用回调。您可以使用它将其加载到字符串中
from ftplib import FTP
ftp = FTP('ftp.ncbi.nlm.nih.gov')
ftp.login() # Username: anonymous password: anonymous@
# Setup a cheap way to catch the data (could use StringIO too)
data = []
def handle_binary(more_data):
data.append(more_data)
resp = ftp.retrbinary("RETR pub/pmc/PMC-ids.csv.gz", callback=handle_binary)
data = "".join(data)
加分:我们一边解压字符串怎么样
轻松模式,使用上面的数据字符串
import gzip
import StringIO
zippy = gzip.GzipFile(fileobj=StringIO.StringIO(data))
uncompressed_data = zippy.read()
稍好一点,完整解决方案:
from ftplib import FTP
import gzip
import StringIO
ftp = FTP('ftp.ncbi.nlm.nih.gov')
ftp.login() # Username: anonymous password: anonymous@
sio = StringIO.StringIO()
def handle_binary(more_data):
sio.write(more_data)
resp = ftp.retrbinary("RETR pub/pmc/PMC-ids.csv.gz", callback=handle_binary)
sio.seek(0) # Go back to the start
zippy = gzip.GzipFile(fileobj=sio)
uncompressed = zippy.read()
实际上,动态解压缩会更好,但我看不到使用内置库实现这一点的方法(至少不容易)。您需要将文件读入本地缓冲区(如read())还是使用FTP命令远程操作它?我想使用FTP远程操作它。如果我错了,请纠正我,但如果我将其读入本地缓冲区,这是否意味着下载文件?我的意思是,您希望将数据从FTP服务器传输到您的PC,然后使用它,对吗?(这就是您链接的SO问题中发生的情况)很抱歉造成混淆,但我不想在我的电脑上传输服务器上的数据。那么,您想在服务器上处理数据,然后在您的电脑上传输结果吗?还是怎样请澄清。谢谢你的回答。我有一个简单的问题,这会不会在我的电脑上下载数据?如果不是它保存数据的位置?它保存在内存中,在一个名为data的字符串中(或者如果一直都是未压缩的)。那么,保存数据的最后一个变量将是未压缩的,对吗?我不知道为什么,但是,如果要用BytesIO替换StringIO,在使用python3.4时将其截断,实际上不需要使用
handle\u binary
函数。只需分别使用callback=data.append
或callback=sio.write
。在仔细阅读Kyle和Stefano之间交换的评论后,在问题的正下方,我为否决这个答案而道歉。然而,凯尔想问的似乎并不是他实际问的。如果你把斯蒂法诺的回答作为对原始问题的回答来阅读,那么它似乎不是真的。在任何情况下,如果Stefano澄清了他的答案(并编辑了答案,让我收回我的反对票),我会很高兴进行修正。我可能错了,但在选项1中,如果读取二进制文件需要多个块,它不会用下一个块覆盖文件吗?不应该将open设置为'ab'
而不是'wb'
@TomBusby,不,'wb'
很好。Python中传递的参数是渴望的(按值调用)。传递给retrbinary
方法的回调只是第二个参数。它被急切地计算,因此,open(…,'wb')
只计算一次,返回文件对象的write
方法是传递给retrbinary
的回调。文件只打开一次进行写入,而不是像您所想的那样每次调用回调。