在python中使用多线程下载文件

编码器

我正在尝试在python cgi中使用多线程将多个文件(ard 25k)放入一个zip文件中。我已经在下面编写了脚本,但是以某种方式我得到的响应的内容长度为0,并且响应中没有数据。这是我第一次在python中使用多线程。我在代码中缺少什么吗?即使在发布数据之前,输出也会被打印吗?

任何帮助将不胜感激。

这是我的代码:

b = StringIO()
z = zipfile.ZipFile(b, 'w', zipfile.ZIP_DEFLATED)

def read_file(link):
    fname = link.split('/')
    fname = fname[-1]
    z.write(link, fname)

if __name__ == '__main__':
    form = cgi.FieldStorage()
    fileLinks = form.getvalue("fileLink")

    p = Pool(10)
    p.map(read_file, fileLinks)
    p.close()
    p.join()
    z.close()
    zipFilename = "DataFiles-" + str(time.time()) + ".zip"   
    length = b.tell()
    sys.stdout.write(
        HEADERS % ('application/zip', zipFilename, zipFilename, length)
    )
    b.seek(0)
    sys.stdout.write(b.read())
    b.close()

相同代码的顺序版本:

 for fileLink in fileLinks:
     fname = fileLink.split('/')
     filename = fname[-1] 
     z.write(fileLink, filename)
z.close()
阿巴拉拉

问题应该是ZipFile.write()ZipFile通常)不是线程安全的。

您必须以某种方式序列化对zip文件的线程访问。这是一种实现方法(在Python 3中):

ziplock = threading.Lock()

def read_file(link):
    fname = link.split('/')
    fname = fname[-1]
    with ziplock:
        z.write(link, fname)

以这种方式进行操作应该没有任何好处,因为锁定实际上是在对zip文件的创建进行序列化。

此版本可以实现一些并行化,该版本在将文件内容添加到zip文件之前先读取文件内容:

def read_file(link):
    fname = link.split('/')
    fname = fname[-1]
    # the file is read in parallel
    contents = open(link).read()
    with ziplock:
        # writes to the zip file a re serialized
        z.writestr(fname, contents)

但是,如果文件位于同一文件系统上,则读操作可能会发挥所有作用,就好像它们已被操作系统序列化一样。

因为是文件,所以并行化的可能目标是进程中受CPU约束的部分,即压缩,而zip格式似乎是不可能的(因为zip文件的行为就像一个目录,因此每个文件都write()必须离开准备在上生成完整档案的状态close())。

如果您可以使用其他压缩格式,则可以使用gizp进行压缩,并以tartarfile)作为存档格式,而无需锁定就可以进行并行化,因为每个文件都可以并行读取和压缩,并且只有tar串联才能完成(.tar.gz.tgz存档格式)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用Python 2.7通过HTTP使用多线程下载文件(异步下载)

来自分类Dev

python中的多处理/多线程下载文件

来自分类Dev

python中的多处理/多线程下载文件

来自分类Dev

使用多线程在Java中下载文件

来自分类Dev

使用多线程在Java中下载文件

来自分类Dev

多线程文件传输/使用javascript下载

来自分类Dev

如何在python中使用Selenium下载文件?

来自分类Dev

在Python中使用Selenium循环下载文件

来自分类Dev

python中使用并行线程的多线程

来自分类Dev

在Swift中使用NSURLSession下载文件

来自分类Dev

在Powershell中使用密码下载文件

来自分类Dev

在 Scrapy 中使用 ItemLoaders() 下载文件

来自分类Dev

Python-在多线程中使用nonce

来自分类Dev

使用多个线程使用JSch下载文件

来自分类Dev

用于在Python中下载NCBI文件的多线程

来自分类Dev

使用Python通过Internet下载文件

来自分类Dev

使用Python通过SSH下载文件

来自分类Dev

使用certutil和Python下载文件

来自分类Dev

使用python硒单击并下载文件

来自分类Dev

使用 Selenium、Python 3 下载文件

来自分类Dev

使用python的多线程读写文件

来自分类Dev

使用PhoneGap下载文件并在AngularJS中使用

来自分类Dev

如何在Python中使用临时令牌从s3存储桶下载文件

来自分类Dev

在Android中使用IntentService从服务器下载文件

来自分类Dev

如何在Rcurl中使用Cookie下载文件

来自分类Dev

如何在Rcurl中使用Cookie下载文件

来自分类Dev

在 iOS Safari 中使用 XHR 下载文件

来自分类Dev

下载文件C#的线程

来自分类Dev

使用cherrypy下载文件