是否可以对javascript中生成的八位字节流进行流式处理?
假设使用一些javascript逻辑从一个小字符串生成一个大字符串,然后强制在浏览器上下载文本文件 这可以使用八位字节流下载,将其作为href,如本答案中所述: 但该解决方案要求在推送下载之前完全生成“文本”, 因此,它必须完全保存在浏览器内存中 是否可以仅使用客户端逻辑在生成文本时对其进行流式处理 例如:是否可以对javascript中生成的八位字节流进行流式处理?,javascript,Javascript,假设使用一些javascript逻辑从一个小字符串生成一个大字符串,然后强制在浏览器上下载文本文件 这可以使用八位字节流下载,将其作为href,如本答案中所述: 但该解决方案要求在推送下载之前完全生成“文本”, 因此,它必须完全保存在浏览器内存中 是否可以仅使用客户端逻辑在生成文本时对其进行流式处理 例如: var inputString = "A"; var outStr = ""; for(var i = 0; i < 10000000 ; i++) { /* concate
var inputString = "A";
var outStr = "";
for(var i = 0; i < 10000000 ; i++)
{
/* concatenate inputString to output on the go */
}
var inputString=“A”;
var-outsr=“”;
对于(变量i=0;i<10000000;i++)
{
/*将inputString连接到运行中的输出*/
}
是&否。否,因为没有一种只使用客户端javascript写入文件的方法。有点。您可以提示用户下载并保存文件,但正如您所提到的,代码必须在下载之前生成整个文件。注意:这里的“流”是指流到文件(不断写入文件)&这里的“仅客户端逻辑”是指在浏览器中
看起来Mozilla一直在研究一种让客户端代码与文件交互的方法。是的。有点它们有自己的功能,允许您与本地计算机文件系统进行交互(写入)。具体来说,有一个函数可以让您。但是,有几个星号:
1) 看起来整个系统都被弃用了;它们鼓励开发人员通过文件I/O进行使用
2) 您必须使用一个系统,该系统允许您以javascript访问Mozilla的XPCOM
(组件库)。如果您想在浏览器中执行此操作,那么看起来只有firefox扩展具有与这些组件交互的适当权限()。如果不想在浏览器中执行此操作,显然可以使用node
毫无疑问,在实施过程中必然会出现更多的复杂情况。但这看起来是最可靠的前进之路,因为OS.File
可以让您访问&basic之类的函数
也就是说,这不是一条伟大的道路,但希望这能给你一个坚实的起点。正如@dandavis提到的,浏览器(即“客户端逻辑”)的设计不允许这种事情。如果一个网站可以与任何用户的本地文件系统进行交互,这将是一个巨大的监督/安全缺陷
其他资源:-可能没有那么有用有一种方法可以做到这一点,但它依赖于仅限Chrome的文件系统API。我们将在沙盒文件系统中创建并写入临时文件,并在完成后将其复制到常规文件系统。这样,您就不必将整个文件存储在内存中。W3C目前没有考虑对ChromeAPI的异步版本进行标准化,但同步verison(使用web workers)正在考虑。如果浏览器支持是一个问题,那么这个答案不适合您 API的工作原理如下: 首先,我们从浏览器中获取
requestFileSystem()
函数。目前它的前缀为“webkit”:
接下来,我们请求一个临时文件系统(这样我们就不需要请求用户权限):
现在我们可以访问文件系统,现在是创建文件的时候了:
var fileOptions = {
create: true, //If the file is not found, create it
exclusive: false //Don't throw an error if the file doesn't exist
};
这里我们调用getFile()
函数,如果文件不存在,它可以创建一个文件。在回调内部,我们可以创建一个新的fileWriter
,用于写入文件。然后将fileWriter
移动到文件的末尾,我们创建一个新的文本blob以附加到它
fileSystem.root.getFile(fileName, fileOptions, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.seek(fileWriter.length);
var blob = new Blob([STRING_TO_WRITE], {type: 'text/plain'});
fileWriter.write(blob);
}, errorHandler);
});
请注意,此API不会保存到普通的用户文件系统。相反,它会保存到一个特殊的沙盒文件夹中。如果要将其保存到用户的文件系统,可以创建文件系统:
链接。当用户单击它时,它将提示他们保存它。保存后,您可以删除临时文件
此函数使用fileEntry
的tour()函数生成filesystem
链接:
var save = function () {
var download = document.querySelector("a[download]");
if (!fileSystem) { return; }
fileSystem.root.getFile(fileName, {create: false, exclusive: true}, function(fileEntry) {
download.href = fileEntry.toURL();
}, errorHandler);
}
使用具有下载属性的链接将强制下载文件
<a download></a>
希望这能实现你想要的。您可以连续地附加到文件中,它不会保留在内存中,但它将位于沙盒文件系统中,直到用户将其保存到常规文件系统中
有关更多信息,请查看此功能,或者如果您想使用更新的同步Web Worker API。我建议使用@quantumwannabe的方式,使用临时沙盒文件来附加块
但是现在有一种新的方式可以使用(在旗帜后面),但将在下一版本的chrome(52)中启用
这就是我要让@KeenanLidral Porter回答不正确的地方。和@quantumwannabe回答不必要的步骤
因为现在有一种直接将流写入文件系统的方法:
它的作用就像有一个服务器发送八位字节流头,并告诉浏览器在服务人员的帮助下下载数据块
const writeStream = streamSaver.createWriteStream('filename.txt')
const encoder = new TextEncoder
let data = 'a'.repeat(1024) // Writing some stuff triggers the save dialog to show
let uint8array = encoder.encode(data + "\n\n")
writeStream.write(uint8array) // Write some data when you got some
writeStream.close() // End the saving
如果您没有找到这个问题的解决方案,那么可以将数据放入一个文件夹中,然后使用它生成下载链接。浏览器可能会将数据缓存在磁盘上,尤其是您不会有大的数据URL。@Phillip我不想将所有内容存储到blob或zip文件中,也不想使用indexDb,流媒体是必需的。否。所有当前的浏览器技术都要求在发送第一个字节之前知道总体大小;只有node.js等较新的服务器端工具才能使用http1.1分块。您将不得不使用许多连接或缓冲区。您可能可以使用WebSocket,但这需要在两端进行一些自定义。请发布该库工作原理的解释,以及它所使用的API的特定代码,而不仅仅是github链接。@InfrastReadableStream
var save = function () {
var download = document.querySelector("a[download]");
if (!fileSystem) { return; }
fileSystem.root.getFile(fileName, {create: false, exclusive: true}, function(fileEntry) {
download.href = fileEntry.toURL();
}, errorHandler);
}
<a download></a>
const writeStream = streamSaver.createWriteStream('filename.txt')
const encoder = new TextEncoder
let data = 'a'.repeat(1024) // Writing some stuff triggers the save dialog to show
let uint8array = encoder.encode(data + "\n\n")
writeStream.write(uint8array) // Write some data when you got some
writeStream.close() // End the saving