【问题标题】:Memory mapped equivalent for FirefoxOSFirefoxOS 的内存映射等效项
【发布时间】:2014-06-11 08:31:52
【问题描述】:

您将如何在 FirefoxOS、Tizen 或任何其他移动纯 JS 解决方案中模拟内存映射文件?

该用例适用于移动浏览器,您需要大量无法放入 RAM 的数据,或者您不想为此浪费 RAM 并希望延迟加载。

我唯一找到的是IndexedDB 或者我能做些什么呢?有更好的技巧或 API 吗?

嗯,看起来Web SQL Database 也可能是 Android、Tizen 或 iOS 上的解决方案。但是 Firefox 不支持它(?)

更新:我问是因为some experiments

【问题讨论】:

    标签: javascript html firefox-os tizen gaia


    【解决方案1】:

    首先,Web SQL 永远不会像 the specification 中解释的那样被标准化,所以它应该只用于基于 WebKit/Blink 的浏览器。

    this queston 中有一个很棒的离线存储选项概述,即使在该问题中考虑了地图图块,我认为它仍然与您的用例相关。

    我相信您在使用 IndexedDB 处理图形数据方面走在了正确的轨道上。概括地说,它是一个键值对异步对象存储(参见Basic Concepts document)。对于您的用例,您可以在 object store 中索引图形节点。例如,LevelGraph 库将图形数据存储在 IndexedDB 中,尽管它是为语义 Web 三元组构建的。 HeliosJS 也值得一提,虽然它是一个内存图数据库。

    编辑:当前的 IndexedDB API 是异步的。规范中起草了synchronous API,它只能用于网络工作者。不幸的是,目前没有引擎实现此功能。有一个pending patch for Gecko,但我没有找到任何关于 Blink 或 WebKit 的计划,所以现在它不是一个有意义的选择。

    可以通过 Web API 访问原始文件。您可以使用XHR2 将(本地)文件加载为二进制Blob。不幸的是,XHR2 主要是为流文件而不是随机访问而设计的,尽管您可以将数据拆分为多个文件并按需请求它们,但这可能会很慢。 目前对文件的直接访问非常有限,FileList and createObjectURL 主要用于直接文件用户输入(通过拖放或文件输入字段),FileSystem API 是recently killedDeviceStorage 是非标准和特权的(特定于 Firefox 操作系统)。您还可以将文件存储在 IndexedDB 中,如FileHandle API 所述。但是,一旦您设法访问原始文件对象,您就可以使用Blob.slice 方法来加载文件块——有一个great example of reading file chunks via upload form。 您可能还想查看jDataView library & friends,它通过更高效的ArrayBuffer 简化了二进制数据的处理。

    编辑: 至于同步 API,localStorage(又名 DOM 存储)也可以考虑。它也是一种键值存储,但比 IndexedDB 简单得多,也更有限:

    • 存储空间有限,usually to 5 MB
    • 每个域/应用程序只有一个 localStorage(您可以在 IndexedDB 中拥有多个命名对象存储)。
    • 只能存储字符串。

    一般来说,localStorage 是有用的 cookie 替代品,但对于存储大量离线数据并没有真正用处。


    总结一下:

    • IndexedDB 是最简单且广泛可用的选项,尽管它可能会很慢、效率低下或在数据量很大时达到内存限制;此外,目前只能使用异步 API。
    • 如果没有用户交互,很难获得原始文件访问权限,并且 API 不稳定且不标准。

    最后,您可以结合这两种方法,有两个选择:

    • 使用XHR2分块解析大文件,并将解析后的节点存入IndexedDB
    • 将大文件存储到 IndexedDB(通过 XHR),使用 FileHandle.getFile 加载 File 对象并使用 Blob.slice 读取其内容。

    在所有情况下,您都可以(应该)使用Web Workers 在后台处理数据操作和计算。

    不管怎样,GraphHopper 看起来很棒,我们真的缺乏这样非平凡的 Firefox OS 离线应用程序,祝你好运!

    【讨论】:

    • 哇,感谢您的深入回答。我会在接下来的几天里看看你的所有建议!
    • @jnv,此类 API 最糟糕的是它们的异步性,而 Java 使用同步 API,GraphHopper 也是如此。而且我们没有机会覆盖 GraphHopper 或 TeaVM 以使用延续传递样式或其他方式。对于 GraphHopper,它会给出过于复杂的 Java 代码,对于 TeaVM,它会带来很大的性能损失,因为大多数方法都将在 CPS 中重写。因此,我们正在寻找在 Web Worker 中同步运行存储 API 的方法。但目前看来,这样的事情是不可能的。
    • @jnv 我认为你的答案是一种可能的方式(我仍然会等待一段时间才能接受它,也许其他人有更多想法:))
    • @AlexeyAndreev 是的,这是从 Java 到 JS 时的关键限制,因为在 Java 中您目前不使用异步 API。但是 TeaVM 可以通过 async+polling 模拟同步访问。我知道这听起来令人毛骨悚然,但结合 WeakMap(请参阅文档:如果 GC 发现它未使用,则丢失密钥)和来自 @jnv 的 Blob.slice(或通过 jDataView)技术可以工作。关键变量将是一个这样的切片(或“段”)的大小,因为如果它太大,则分配的内存过多(+初始等待时间太长),如果太小,则可能会出现太多此类轮询操作发生
    • 我明白,JS 的异步特性在这里是一个真正的问题。 @AlexeyAndreev:有一个用于 IDB 的同步 API 已计划,但未在任何地方实现:developer.mozilla.org/en-US/docs/Web/API/… - 所以 Blob.slice 似乎是要走的路,因为您只需要一些异步代码的包装器。另外我建议看看现有的转译器如何处理同步到异步流:github.com/jashkenas/coffeescript/wiki/…
    猜你喜欢
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    相关资源
    最近更新 更多