WebAssembly002 IDBFS 浏览器文件存储

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

在这里插入图片描述在这里插入图片描述

// https://github.com/robnyman/robnyman.github.com/tree/master/html5demos/indexeddb
// https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
// https://firefox-source-docs.mozilla.org/devtools-user/storage_inspector/indexeddb/
(function () {
    // 获取 IndexedDB 相关对象,适配不同浏览器的前缀
    var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB,
        IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction,
        dbVersion = 1.0;

    // 创建或打开名为 "elephantFiles" 的 IndexedDB 数据库
    var request = indexedDB.open("elephantFiles", dbVersion),
        db,
        createObjectStore = function (dataBase) {
            // 创建一个名为 "elephants" 的对象存储空间
            console.log("Creating objectStore");
            dataBase.createObjectStore("elephants");
        },

        getImageFile = function () {
            // 创建 XMLHttpRequest 对象
            var xhr = new XMLHttpRequest(),
                blob;

            // 发送 GET 请求以获取图像文件
            xhr.open("GET", "elephant.png", true);
            // 设置响应类型为 blob
            xhr.responseType = "blob";

            xhr.addEventListener("load", function () {
                if (xhr.status === 200) {
                    console.log("Image retrieved");

                    // 将响应的 blob 存储到 IndexedDB
                    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);

            // 将 blob 存储到对象存储空间
            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);

                // 获取 window.URL 对象
                var URL = window.URL || window.webkitURL;

                // 创建和撤销 ObjectURL
                var imgURL = URL.createObjectURL(imgFile);

                // 设置 img 元素的 src 属性为 ObjectURL
                var imgElephant = document.getElementById("elephant");
                imgElephant.setAttribute("src", imgURL);

                // 撤销 ObjectURL
                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);
    };
})();

A minimum working example of making use of IDBFS (browser storage)

$ 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() {  // <button οnclick="InboxHandler()" >save to IDBFS</button><br>
          SaveData(document.getElementById('inbox').value);
       }

       function OutboxHandler() { // <button οnclick="OutboxHandler()" >read from IDBFS</button><br>
          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) { 
         // provide the DOM side a way to execute code after directory is mounted
         if (typeof Module.OnDataMounted !== 'undefined') {
            Module.OnDataMounted();
         }
      } );
   );

   emscripten_exit_with_live_runtime();
}

idbfs.js

localForage项目 : 离线存储,改进。使用简单但功能强大的 API 包装 IndexedDB、WebSQL 或 localStorage

CG

  • 22
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值