c++ Emscripten:提供下载/保存生成的MEMFS文件

kt06eoxx  于 2023-01-15  发布在  其他
关注(0)|答案(2)|浏览(209)

我玩emscripten是为了好玩,我编译了一个旧的模拟器程序,可以在浏览器中运行。
程序将输出保存为一个数据文件,由于我没有做任何特殊的操作,它应该驻留在MEMFS(内存文件系统)中。
我如何允许用户从MEMFS下载结果文件?我可以触发浏览器的常规保存文件对话框吗?

enyaitl3

enyaitl31#

明白了

  • 在编译期间将文件系统添加到EXTRA_EXPORTED_RUNTIME_METHODS。
$ emcc --bind -std=c++11 \
       -s EXTRA_EXPORTED_RUNTIME_METHODS=FS \
       -o main.js *.cpp
  • 将下面的函数添加到.html或.js文件中。
function offerFileAsDownload(filename, mime) {
  mime = mime || "application/octet-stream";

  let content = Module.FS.readFile(filename);
  console.log(`Offering download of "${filename}", with ${content.length} bytes...`);

  var a = document.createElement('a');
  a.download = filename;
  a.href = URL.createObjectURL(new Blob([content], {type: mime}));
  a.style.display = 'none';

  document.body.appendChild(a);
  a.click();
  setTimeout(() => {
    document.body.removeChild(a);
    URL.revokeObjectURL(a.href);
  }, 2000);
}
  • 运行后调用函数(选项1):
<script>
// This must go BEFORE sourcing main.js:
var Module = {
  onRuntimeInitialized: () => {
    Module.postRun.push(() => offerFileAsDownload("filename.ext", "mime/type"));
  }
};
</script>
<script src="main.js"></script>
  • 在C++代码末尾调用函数(OPTION 2):
int main() {
  // ...
  emscripten::val::global("window").call<void>(
    "offerFileAsDownload",
    string("filename.ext"),
    string("mime/type")
  );
  // ...
}
yeotifhr

yeotifhr2#

我已经发布了一个小型的只包含头文件的C++库,它允许在Emscripten中下载和上传文件:
https://github.com/Armchair-Software/emscripten-browser-file
这比另一个答案简单得多,只需使用EM_JS-下面的示例来自上面的示例:

EM_JS(void, download, (char const *filename, char const *mime_type, void const *buffer, size_t buffer_size), {
  /// Offer a buffer in memory as a file to download, specifying download filename and mime type
  var a = document.createElement('a');
  a.download = UTF8ToString(filename);
  a.href = URL.createObjectURL(new Blob([new Uint8Array(Module.HEAPU8.buffer, buffer, buffer_size)], {type: UTF8ToString(mime_type)}));
  a.click();
});

这适用于任何内存缓冲区,-如果您想特别引用MEMFS,可以使用Module.FS.readFile(filename)

相关问题