栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在FTP服务器上的zip文件中获取文件名,而无需下载整个存档

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在FTP服务器上的zip文件中获取文件名,而无需下载整个存档

您可以实现一个类似文件的对象,该对象从FTP读取数据,而不是从本地文件读取数据。并将其传递给

ZipFile
构造函数,而不是(本地)文件名。

一个简单的实现可以像:

from ftplib import FTPfrom ssl import SSLSocketclass FtpFile:    def __init__(self, ftp, name):        self.ftp = ftp        self.name = name        self.size = ftp.size(name)        self.pos = 0    def seek(self, offset, whence):        if whence == 0: self.pos = offset        if whence == 1: self.pos += offset        if whence == 2: self.pos = self.size + offset    def tell(self):        return self.pos    def read(self, size = None):        if size == None: size = self.size - self.pos        data = B""        # based on FTP.retrbinary         # (but allows stopping after certain number of bytes read)        ftp.voidcmd('TYPE I')        cmd = "RETR {}".format(self.name)        conn = ftp.transfercmd(cmd, self.pos)        try: while len(data) < size:     buf = conn.recv(min(size - len(data), 8192))     if not buf:         break     data += buf # shutdown ssl layer (can be removed if not using TLS/SSL) if SSLSocket is not None and isinstance(conn, SSLSocket):     conn.unwrap()        finally: conn.close()        try: ftp.voidresp()        except: pass        self.pos += len(data)        return data

然后您可以像这样使用它:

ftp = FTP(host, user, passwd)ftp.cwd(path)ftpfile = FtpFile(ftp, "archive.zip")zip = zipfile.ZipFile(ftpfile)print(zip.namelist())

上面的实现是微不足道且效率低下的。它开始下载小块数据(至少三个),以检索包含的文件列表。可以通过读取和缓存较大的块进行优化。但这应该可以给您想法。


特别是,您可以利用仅阅读清单的事实。该列表位于ZIP归档文件的和。因此,您一开始就可以下载最后(大约)10
KB的数据。这样您就可以完成

read
该缓存中的所有呼叫。


知道这一点,您实际上可以进行一些小小的改动。由于清单位于存档的末尾,因此您实际上只能下载存档的末尾。虽然下载的ZIP将被破坏,但仍可以列出。这样,您将不需要

FtpFile
课程。您甚至可以将列表下载到内存(
StringIO
)。

zipstring = StringIO()name = "archive.zip"size = ftp.size(name)ftp.retrbinary("RETR " + name, zipstring.write, rest = size - 10*2024)zip = zipfile.ZipFile(zipstring)print(zip.namelist())

如果

BadZipfile
由于10 KB太小而无法包含整个清单而导致异常,则可以使用更大的块重试代码。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/610817.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号