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

Javascript 提示将多个文件流作为一个文件下载,javascript,jquery,Javascript,Jquery,假设有一台服务器存储多个文件(不一定是文本文档): http:////file0001.txt ... http:////file9999.txt 若用户要将所有这些文件作为一个文件下载,我将如何使用javascript进行下载 通常情况下,用户必须下载9999个文件并将其加入到自己的驱动器中。 当javascript获取多个文件时,如何提示下载一个文件并流式处理多个文件的数据,就像流式处理一个大文件一样 我想应该是这样的(请原谅我缺少javascript,只是想解释一下): 下载每个文件并将其

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

若用户要将所有这些文件作为一个文件下载,我将如何使用javascript进行下载

通常情况下,用户必须下载9999个文件并将其加入到自己的驱动器中。 当javascript获取多个文件时,如何提示下载一个文件并流式处理多个文件的数据,就像流式处理一个大文件一样

我想应该是这样的(请原谅我缺少javascript,只是想解释一下):

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

我想知道这是否可能。我可以用python写,但那是另一回事了。我想让它成为网站上的javascript函数

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

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


这是streamSaver内部的功能,但消除了所有麻烦…
我将向您展示一个使用es6和

它没有经过测试,只是一个令人恼火的想法。 这将消耗很少的内存,但如果您想使用StreamSaver,它仅限于闪烁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')
})
let download=Promise.coroutine(函数*(文件){
const fileStream=streamSaver.createWriteStream('onefile.txt')
const writeStream=fileStream.getWriter()
//以后你就可以简单地做了
//将res.body.pipeTo(文件流)而不是泵送
for(让文件中的文件){
let res=收益获取(文件)
让reader=res.body.getReader()
让泵=()=>reader.read()读取
.然后({value,done})=>!done&&
//写一块,然后得到下一块
writeStream.write(值)。然后(泵)
)
产量泵()
}
//完成写入后关闭流
writeStream.close()
}
下载([
'http:////file0001.txt',
'http:////file9999.txt'
]).然后(()=>{
警报(“全部完成”)
})

有什么原因不想将它们与服务器端的python结合起来,然后将生成的blob流式处理?
http:////aggregator.py
,让该文件结合文件和输出标题,告诉浏览器以文本文件或其他形式下载结果。我本来想这样做,是的,如果不可能,我会这样做使用Javascript。我希望创建一个有目的的网站,供人们免费在线使用,一个做一些事情的工具。如果是公共服务,我不能承载那么多文件。我明白了,这是有道理的。你最好的选择可能是使用ajax下载每个文件,将文件读入隐藏的画布,然后使用类似于或的方法让用户将画布保存为blob。如果每个文件都是mpeg2传输流,每个文件都是5mb,并且concaternated result.ts是5gb?这不能放在画布中,是吗?:oDon不能对画布做任何事情…使用将所有文件添加到一个文件中。如果文件太大,则使用jszip。否则就可以了。StreamSaver.js在Blink(chrome和opera)中工作。例如,它可以与yield和bluebird协同程序交换,但我使用了async,让它启动您想做什么(async/await还不可用)除非你使用Transpilert,否则这看起来很有趣,我会完全尝试一下。我不太懂javascript,所以我必须学习这一部分,因为这是我在该网站上真正需要的唯一功能。我很快会回来报告:)一个问题,我能用
还是Node.js的方式?我得到了
未捕获的语法错误:意外的令牌函数
,即使我
使用strict这只是客户端,所以在
标记中执行。这在节点中不起作用。它不允许我在
标记中使用它。正如你所说,这是es6/7。我一使用
async
它就会抛出一个错误。
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')
})