提示将多个文件的流下载为一个

时间:2016-08-17 14:41:42

标签: javascript jquery

假设有一个服务器存储多个文件(不一定是文本文件):
http://<server>/<path>/file0001.txt ... http://<server>/<path>/file9999.txt

如果用户要将所有这些文件作为一个文件下载,我将如何在javascript中进行操作?

通常用户必须下载9999个文件并将其加入到他的驱动器中。 如何在javascript获取文件的同时提示下载文件并流式传输多个文件的数据,就像它是一个大文件流一样。

我想它会是这样的(请原谅我缺少javascript,只是试图解释):

With (download prompt of 'onefile.txt') as connection:
While connection is open:
    For file in file_list:
        get file
        return file.contents
    connection close

下载每个文件并将其存储在内存中直到检索到最后一个文件并不是一个好主意,因为该文件的整体大小可能非常大。

我想知道这是否可能。我可以在python中编写它,但这是另一个故事。我想在网站上建立一个javascript函数。

1 个答案:

答案 0 :(得分:1)

  

我很惊讶javascript不能只创建一个“虚拟本地主机连接”,它使用一些生成器“产生”每个文件的内容......

好吧,如果您使用服务工作者,那么您可以操作响应并为其提供可读“流”,您可以“生成”每个文件的内容......

这就是streamSaver在内部的剂量,但带走了所有的麻烦...
我将使用es6和StreamSaver.js

向您展示一个示例

它没有经过测试,只是一个粗鲁的想法。 这将占用很少的内存,但如果您想使用StreamSaver

,它仅限于Blink ATM
let download = Promise.coroutine(function* (files) {
    const fileStream = streamSaver.createWriteStream('onefile.txt')
    const writeStream = fileStream.getWriter()

    // Later you will be able to just simply do
    // yield res.body.pipeTo(fileStream) instead of pumping

    for (let file of files) {
        let res = yield fetch(file)
        let reader = res.body.getReader()

        let pump = () => reader.read()
        .then(({ value, done }) => !done &&
            // Write one chunk, then get the next one
            writeStream.write(value).then(pump)
        )

        yield pump()
    }

    // Close the stream when you are done writing
    writeStream.close()
}

download([
    'http://<server>/<path>/file0001.txt',
    'http://<server>/<path>/file9999.txt'
]).then(() => {
    alert('all done')
})