1.文件系统
2.文件系统类型
- Emscripten 提供了多个文件系统,可以挂载这些文件系统,以帮助处理持久性,具体取决于执行上下文
2.1 MEMFS
- 这是初始化运行时挂载的默认文件系统。所有文件都严格存在于内存中,重新加载页面时,写入它们的任何数据都将丢失。
2.2 NODEFS
- NODEFS文件系统仅在node.js中运行时使用。
- 此文件系统允许节点中的程序将主机文件系统上的目录(通过挂载操作)映射到 Emscripten 虚拟文件系统中的目录。
- 它使用节点的同步 FS API 立即将写入 Emscripten 文件系统的任何数据持久化到本地磁盘。
2.3 NODERAWFS
- NODERAWFS文件系统仅在node.js中运行时使用。
- 这是一个特殊的后端,因为它用直接Node.js操作取代了所有正常的文件系统访问,而无需执行 FS.mount()。初始工作目录将与 process.cwd() 相同,而不是 VFS 根目录。由于此模式直接使用Node.js访问操作系统上的真实本地文件系统,因此代码不一定在操作系统之间可移植 - 它将像Node.js程序一样可移植,这意味着底层操作系统处理权限和错误等的方式可能会明显存在差异。到目前为止,这主要在 Linux 上进行了测试。
2.4 IDBFS
IDBFS的相关实现
图像文件存储到 IndexedDB
(function () {
var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB,
IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction,
dbVersion = 1.0;
var request = indexedDB.open("elephantFiles", dbVersion),
db,
createObjectStore = function (dataBase) {
console.log("Creating objectStore");
dataBase.createObjectStore("elephants");
},
getImageFile = function () {
var xhr = new XMLHttpRequest(),
blob;
xhr.open("GET", "elephant.png", true);
xhr.responseType = "blob";
xhr.addEventListener("load", function () {
if (xhr.status === 200) {
console.log("Image retrieved");
putElephantInDb(xhr.response);
}
}, false);
xhr.send();
},
putElephantInDb = function (blob) {
console.log("Putting elephants in IndexedDB");
var readWriteMode = typeof IDBTransaction.READ_WRITE == "undefined" ? "readwrite" : IDBTransaction.READ_WRITE;
var transaction = db.transaction(["elephants"], readWriteMode);
var put = transaction.objectStore("elephants").put(blob, "image");
transaction.objectStore("elephants").get("image").onsuccess = function (event) {
var imgFile = event.target.result;
console.log("Got elephant!" + imgFile);
var URL = window.URL || window.webkitURL;
var imgURL = URL.createObjectURL(imgFile);
var imgElephant = document.getElementById("elephant");
imgElephant.setAttribute("src", imgURL);
imgElephant.onload = function () {
window.URL.revokeObjectURL(this.src);
}
};
};
request.onerror = function (event) {
console.log("Error creating/accessing IndexedDB database");
};
request.onsuccess = function (event) {
console.log("Success creating/accessing IndexedDB database");
db = request.result;
db.onerror = function (event) {
console.log("Error creating/accessing IndexedDB database");
};
if (db.setVersion) {
if (db.version != dbVersion) {
var setVersion = db.setVersion(dbVersion);
setVersion.onsuccess = function () {
createObjectStore(db);
getImageFile();
};
} else {
getImageFile();
}
} else {
getImageFile();
}
}
request.onupgradeneeded = function (event) {
createObjectStore(event.target.result);
};
})();
$ git clone https://github.com/dudeofx/webassembly-IDBFS-barebones.git
$cd webassembly-IDBFS-barebones
$ emcc IDBFS_test.c -s WASM=1 -s EXTRA_EXPORTED_RUNTIME_METHODS='["cwrap", "ccall"]' -o IDBFS_utils.js
emcc: warning: EXTRA_EXPORTED_RUNTIME_METHODS is deprecated, please use EXPORTED_RUNTIME_METHODS instead [-Wdeprecated]
cache:INFO: generating system asset: symbol_lists/3a50eb4034c25d88d9f979c78f40b4d80081b428.json... (this will be cached in "/home/pdd/Downloads/emsdk/upstream/emscripten/cache/symbol_lists/3a50eb4034c25d88d9f979c78f40b4d80081b428.json" for subsequent builds)
cache:INFO: - ok
$ python -m http.server
- 实现效果如下,刷新网页时内容清除
<script src="IDBFS_utils.js"></script>
<script type='text/javascript'>
var LoadData = Module.cwrap('LoadData', 'string', null);
var SaveData = Module.cwrap('SaveData', null, ['string']);
function InboxHandler() {
SaveData(document.getElementById('inbox').value);
}
function OutboxHandler() {
document.getElementById('outbox').value = LoadData();
}
Module.OnDataMounted = OutboxHandler;
</script>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
char *LoadData() {
int fd;
int size;
char *buff;
fd = open("/data/textfile.txt", O_RDONLY);
if (fd == -1) return strerror(errno);
size = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
buff = (char *) malloc(size+1);
read(fd, buff, size);
buff[size] = '\0';
close(fd);
return buff;
}
EMSCRIPTEN_KEEPALIVE
void SaveData(char *data) {
int fd;
int size;
if (data == NULL) return;
fd = open("/data/textfile.txt", O_CREAT | O_WRONLY, 0666);
if (fd == -1) {
printf("ERROR: could not open the file for writing!\n, %s\n", strerror(errno));
return;
}
size = strlen(data);
printf("saving %i bytes... %s\n", size, data);
write(fd, data, size);
ftruncate(fd, size);
close(fd);
EM_ASM ( FS.syncfs(false, function (err) {} ); );
}
int main() {
EM_ASM(
FS.mkdir('/data');
FS.mount(IDBFS, {}, '/data');
FS.syncfs(true, function (err) {
if (typeof Module.OnDataMounted !== 'undefined') {
Module.OnDataMounted();
}
} );
);
emscripten_exit_with_live_runtime();
}
idbfs.js
CG