在 Blazor 中保存使用 Cs 创建的大文件
Save large file created with Cs in Blazor
我正在做一个周末项目,该项目使用 Blazor (webassmbly) 将来自其他站点的下载汇总到一个 zip 文件中。
zip 文件是用 c# 代码创建的,需要保存在本地计算机上。我使用的是 的修改版本,因为文件大小很容易超过 400 mb。
我的版本对 js 调用进行了分区,使其不会立即溢出 webassembly VM,但在达到一定的文件大小后,它发生了,我得到了以下异常:
WASM: Try saving 213776418bytes --my message
blazor.webassembly.js:1 WASM: GC_MAJOR_SWEEP: major size: 1808K in use: 94964K
blazor.webassembly.js:1 WASM: GC_MAJOR: (LOS overflow) time 71.98ms, stw 72.00ms los size: 486832K in use: 481083K
WASM: Error: Garbage collector could not allocate 16384 bytes of memory for major heap section.
Uncaught (in promise) ExitStatus {name: "ExitStatus", message: "Program terminated with exit(1)", status: 1}
除了将文件内容传输到 js 然后用 Blob 保存之外,目前还有其他方法可以从 WebAssembly 保存文件吗?
我找到了解决办法。随着 .Net5 的最新更新,现在可以使用 IJSUnmarshalledRuntime
。这使一切变得容易得多。请注意,似乎仍然存在限制或其他限制我被迫将我的文件分区到大约 200mb,但解决方案非常快并且似乎工作得“很好”。警告:仅适用于 Webassembly Blazor!
首先使用 FileUtil 编写:
public static class FileUtil
{
public static void SaveAs(this IJSRuntime js, string filename, MemoryStream data)
{
var rt = js as IJSUnmarshalledRuntime;
var dataArray = data.ToArray();
rt.InvokeUnmarshalled<string, byte[], object>(
"saveAsFile",
filename,
dataArray);
}
}
然后使用这个js函数:
function saveAsFile(filenamePointer, contentPointer) {
var parts = Blazor.platform.toUint8Array(contentPointer);
var filename = BINDING.conv_string(filenamePointer);
var blob = new Blob([parts], { type: "application/octet-stream" });
if (navigator.msSaveBlob) {
//Download document in Edge browser
navigator.msSaveBlob(blob, filename);
}
else {
var link = document.createElement('a');
link.download = filename;
link.href = URL.createObjectURL(blob);
document.body.appendChild(link); // Needed for Firefox
link.click();
document.body.removeChild(link);
}
}
我正在做一个周末项目,该项目使用 Blazor (webassmbly) 将来自其他站点的下载汇总到一个 zip 文件中。
zip 文件是用 c# 代码创建的,需要保存在本地计算机上。我使用的是
我的版本对 js 调用进行了分区,使其不会立即溢出 webassembly VM,但在达到一定的文件大小后,它发生了,我得到了以下异常:
WASM: Try saving 213776418bytes --my message
blazor.webassembly.js:1 WASM: GC_MAJOR_SWEEP: major size: 1808K in use: 94964K
blazor.webassembly.js:1 WASM: GC_MAJOR: (LOS overflow) time 71.98ms, stw 72.00ms los size: 486832K in use: 481083K
WASM: Error: Garbage collector could not allocate 16384 bytes of memory for major heap section.
Uncaught (in promise) ExitStatus {name: "ExitStatus", message: "Program terminated with exit(1)", status: 1}
除了将文件内容传输到 js 然后用 Blob 保存之外,目前还有其他方法可以从 WebAssembly 保存文件吗?
我找到了解决办法。随着 .Net5 的最新更新,现在可以使用 IJSUnmarshalledRuntime
。这使一切变得容易得多。请注意,似乎仍然存在限制或其他限制我被迫将我的文件分区到大约 200mb,但解决方案非常快并且似乎工作得“很好”。警告:仅适用于 Webassembly Blazor!
首先使用 FileUtil 编写:
public static class FileUtil
{
public static void SaveAs(this IJSRuntime js, string filename, MemoryStream data)
{
var rt = js as IJSUnmarshalledRuntime;
var dataArray = data.ToArray();
rt.InvokeUnmarshalled<string, byte[], object>(
"saveAsFile",
filename,
dataArray);
}
}
然后使用这个js函数:
function saveAsFile(filenamePointer, contentPointer) {
var parts = Blazor.platform.toUint8Array(contentPointer);
var filename = BINDING.conv_string(filenamePointer);
var blob = new Blob([parts], { type: "application/octet-stream" });
if (navigator.msSaveBlob) {
//Download document in Edge browser
navigator.msSaveBlob(blob, filename);
}
else {
var link = document.createElement('a');
link.download = filename;
link.href = URL.createObjectURL(blob);
document.body.appendChild(link); // Needed for Firefox
link.click();
document.body.removeChild(link);
}
}