假设有一个服务器存储多个文件(不一定是文本文档):
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 函数。
最佳答案
I'm surprised javascript can't just create a "virtual localhost connection" where it uses some generator to "yield" the contents of each file...
好吧,如果您使用服务工作人员,那么您可以操纵响应并为其提供一个可读流,您可以“生成”每个文件的内容...
<小时/>这就是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')
})
关于javascript - 提示将多个文件作为一个流下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38999751/