WebAssembly002 IDBFS 浏览器文件存储

news2024/11/24 23:09:10

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

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

// 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

  • https://github.com/mlveis/idbfs在这里插入图片描述

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1433971.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从奥迪Quattro到碧然德:揭秘技术品牌成功打造与推广的秘诀

在当前全球化和信息化快速发展的背景下&#xff0c;技术品牌的打造不仅是企业竞争力提升的重要途径&#xff0c;也是企业实现长远发展的基石。通过深入剖析&#xff0c;我们认识到&#xff0c;技术品牌的建设并非一蹴而就的过程&#xff0c;而是需要企业准确把握市场趋势&#…

全球十大优质黄金期货交易平台app软件排行榜(2024版)

对于选择黄金期货交易平台app软件&#xff0c;有几个关键因素需要考虑。首先是app平台的声誉和信誉度&#xff1b;其次是app平台的交易费用和手续费。 第三是app平台的交易品种和交易功能&#xff1b;第四是app平台的安全性和风险控制措施&#xff1b;最后还要考虑app平台的客…

论文阅读-一个用于云计算中自我优化的通用工作负载预测框架

论文标题&#xff1a;A Self-Optimized Generic Workload Prediction Framework for Cloud Computing 概述 准确地预测未来的工作负载&#xff0c;如作业到达率和用户请求率&#xff0c;对于云计算中的资源管理和弹性非常关键。然而&#xff0c;设计一个通用的工作负载预测器…

Redis核心技术与实战【学习笔记】 - 24.Redis 数据分片方案选择:Codis 和 Redis Cluster

简述 Redis 的切片集群使用多个实例保存数据&#xff0c;能很好的应对大数据量的场景。在《4.Redis 切片集群》中&#xff0c;介绍了 Redis 官方提供的切片集群方法 Redis Cluster。本章&#xff0c;再来学习下&#xff0c;在 Redis Cluster 方案正式发布前&#xff0c;业界广…

C#,纽曼-康韦数(Newman Conway Number)的算法与源代码

John Henrry Newman 1 纽曼-康韦数 纽曼-康韦数&#xff08;Newman Conway Number&#xff09;序列是生成以下整数序列的序列。 1 1 2 2 3 4 4 4 5 6 7 7… 在数学上&#xff0c;纽曼-康韦数的序列P&#xff08;n&#xff09;由递推关系定义&#xff1a; (1) P&#xff08…

【C++历练之路】二叉搜索树的学习应用及其实现

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 前言&#x1f354;&#xff1a; 我们之前学过一些查找关键数据的办法&#xff0c;排序二分查找。但是这种方法的插入的时间复杂的太高&#xff0c;今天我们来学习一个更好的办法来应对数据查找——二叉搜索树。 目录…

深入实战:ElasticSearch的Rest API与迭代器模式在高效查询中的应用

在我们公司&#xff0c;大多数Java开发工程师在项目中都有使用Elasticsearch的经验。通常&#xff0c;他们会通过引入第三方工具包或使用Elasticsearch Client等方式来进行数据查询。然而&#xff0c;当涉及到基于Elasticsearch Rest API的/_sql?formatjson接口时&#xff0c;…

Fink CDC数据同步(一)环境部署

1 背景介绍 Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行&#xff0c;并能以内存速度和任意规模进行计算。 Flink CDC 是 Apache Flink 的一组源连接器&#xff0c;基于数据库日志的…

【深度学习】从0完整讲透深度学习第2篇:TensorFlow介绍和基本操作(代码文档已分享)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论深度学习相关知识。可以让大家熟练掌握机器学习基础,如分类、回归&#xff08;含代码&#xff09;&#xff0c;熟练掌握numpy,pandas,sklearn等框架使用。在算法上&#xff0c;掌握神经网络的数学原理&#xff0c;手动实…

leetcode(滑动窗口)3.无重复字符的最长字串(C++)DAY2

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示…

机器学习笔记-集成学习

机器学习笔记-集成学习 随机森林随机森林bagging和boostingGBDT 随机森林 随机森林 mac上optionenter即可导入包随机森林就是bagging决策树 总结 bagging和boosting 公式和例子 GBDT

Facebook的数字合作愿景:创新与未来发展

随着科技的飞速发展&#xff0c;Facebook一直处于数字创新的前沿&#xff0c;致力于构建开放、智能、社交的数字社交体验。本文将深入探讨Facebook的数字合作愿景&#xff0c;探索其在创新与未来发展方面的雄心壮志。 引言 在当今数字化时代&#xff0c;社交媒体不仅是人们沟通…

2 月 5 日算法练习- 字符串

人物相关性分析 思路&#xff1a;枚举前缀和。枚举字符串中的 Bob 位置利用前缀和来记录&#xff0c;然后枚举 Alice 的位置&#xff0c;通过判断 Bob 在 Alice 前面还是后面来进行不同的前缀和差值计算距离 k 距离中 Bob 的个数求和就是答案&#xff0c;复杂度是 On。注意 Bob…

Ubuntu使用Docker部署Nginx并结合内网穿透实现公网远程访问

文章目录 1. 安装Docker2. 使用Docker拉取Nginx镜像3. 创建并启动Nginx容器4. 本地连接测试5. 公网远程访问本地Nginx5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 在开发人员的工作中&#xff0c;公网远程访问内网是其必备的技术需求之一。对于…

OpenResty 安装

安装OpenResty 1.安装 首先你的Linux虚拟机必须联网 1&#xff09;安装开发库 首先要安装OpenResty的依赖开发库&#xff0c;执行命令&#xff1a; yum install -y pcre-devel openssl-devel gcc --skip-broken2&#xff09;安装OpenResty仓库 你可以在你的 CentOS 系统中…

Redis核心技术与实战【学习笔记】 - 14.Redis 旁路缓存的工作原理及如何选择应用系统的缓存类型

概述 我们知道&#xff0c;Redis 提供了高性能的数据存取功能&#xff0c;广泛应用在缓存场景中&#xff0c;既可以提升业务的响应速度&#xff0c;又可以避免把高并发的请求发送到数据库。 如果 Redis 做缓存时出现了问题&#xff0c;比如说缓存失效&#xff0c;那么&#x…

【LeetCode: 292. Nim 游戏+ 博弈问题】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

openssl3.2 - use openssl cmd create ca and p12

文章目录 openssl3.2 - use openssl cmd create ca and p12概述笔记实验的openssl环境建立CA生成私钥和证书请求生成CA证书用CA签发应用证书用CA对应用证书进行签名将已经签名好的PEM证书封装为P12证书验证P12证书是否可用END openssl3.2 - use openssl cmd create ca and p12 …

Linux openKylin(开放麒麟)系统SSH服务安装配置与公网远程连接

文章目录 前言1. 安装SSH服务2. 本地SSH连接测试3. openKylin安装Cpolar4. 配置 SSH公网地址5. 公网远程SSH连接6. 固定SSH公网地址7. SSH固定地址连接8. 结语 前言 openKylin是中国首个基于Linux 的桌面操作系统开发者平台&#xff0c;通过开放操作系统源代码的方式&#xff…

网桥与网关

文章目录 概要网桥网关联系与区别参考文章 概要 网桥和网关的理解 网桥 几个名词的概念 网关 联系与区别 参考文章 如何通俗地解释什么是网桥&#xff1f; 网关到底是什么求通俗易懂讲解? 网桥&#xff1a;网桥也叫桥接器&#xff0c;是连接两个局域网的一种存储/转发…