1.文件系统
文件系统 API官方文档 https://emscripten.org/docs/api_reference/Filesystem-API.html JavaScript 通常在 Web 浏览器的沙盒环境中运行,没有 直接访问本地文件系统。Emscripten 模拟了一个文件系统。要访问的文件应预加载或嵌入到虚拟文件系统中。
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
此文件系统基于浏览器的IndexedDB,仅用于在浏览器中运行代码时。有许多 Web 技术在客户端(即本地磁盘)存储各种数据。IndexedDB 是最常见的一个。浏览器计算分配给 Web 数据存储的空间以及达到该限制时要删除的内容的过程并不简单,并且在浏览器之间有所不同。浏览器存储限制和回收标准尝试解释这是如何工作的,至少在火狐的情况下是如此。 克服浏览器不为持久性存储提供同步 API 的限制,因此(默认情况下)所有写入仅暂时存在于内存中。 indexedDB是一个本地关系型数据库.和webStorage同期(2015年)普及到浏览器的. 存储量理论没有上限(实际上各个浏览器还是会进行一定的限制的)。支持异步操作,性能会更高。 原生支持存储js对象。是个数据库,功能强大。
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
https://github.com/mlveis/idbfs
CG
4种前端本地存储方法 在浏览器中持久化保存数据 Pyodide是个可以在浏览器中跑的WebAssembly(wasm)应用。它基于CPython的源代码进行了扩展,使用emscripten编译成为wasm linux同步机制(fdatasync fsync syncfs sync)详解 https://www.cntofu.com/book/150/zh/ch3-runtime/ch3-03-fs.md FS.syncfs https://github.com/tiagobento/isomorphic-git-web-worker-emscripten-idbfs/blob/main/README.md Native HDF5 in the browser: jsfive and h5wasm – Brian B Maranville, NIST Center for Neutron Research Emscripten Tutorial for Web Developers