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

Posted

技术标签:

【中文标题】Emscripten:提供下载/保存生成的 MEMFS 文件【英文标题】:Emscripten: Offer to download/save a generated MEMFS file 【发布时间】:2019-01-31 18:14:40 【问题描述】:

我玩 emscripten 是为了好玩,并编译了我的一个旧模拟器程序以在浏览器中运行。

程序将输出保存为数据文件,由于我没有做任何特别的事情,它应该驻留在 MEMFS(内存文件系统)上。

如何允许用户从 MEMFS 下载生成的文件?我可以触发浏览器的常规保存文件对话框吗?

【问题讨论】:

【参考方案1】:

知道了:

在编译期间将 FS 添加到 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);

在 postRun 上调用函数(选项 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++ 代码末尾调用函数(选项 2):
int main() 
  // ...
  emscripten::val::global("window").call<void>(
    "offerFileAsDownload",
    string("filename.ext"),
    string("mime/type")
  );
  // ...

【讨论】:

选项 2 还需要包含 emscripten/bind.h。

以上是关于Emscripten:提供下载/保存生成的 MEMFS 文件的主要内容,如果未能解决你的问题,请参考以下文章

内存变量文件(.mem)怎么生成和打开

如何使用 emscripten 生成独立的 WebAssembly

emscripten:在 C 中使用全局变量

Emscripten: emmake 生成 .js 文件

如何使用 emscripten 将文件从 C 保存到浏览器存储

如何使用 es6 导入加载 emscripten 生成的模块?