如何有效地将大文件加载到 IndexedDB 存储中?我的应用程序在超过 100,000 行时崩溃
Posted
技术标签:
【中文标题】如何有效地将大文件加载到 IndexedDB 存储中?我的应用程序在超过 100,000 行时崩溃【英文标题】:How to efficiently load large files into IndexedDB storage? My app is crashing at over 100,000 rows 【发布时间】:2019-06-03 16:25:25 【问题描述】:我有一个特定的 Web 应用程序,它依赖于从客户端的本地文件上传大量数据行。目的是将这些数据存储在 indexeddb 中。
数据只有两列我感兴趣,每列包含不超过 25 个字符的字符串,但最多可以有 100 万行。
阅读了很多问题和文档,我创建了一些代码,这些代码似乎适用于创建具有 20,000 行以下的较小数据集的 indexeddb,但会在较大的数据上中断。
我确定这是由于设计不佳,因为我是这种工作风格的新手,或者可能在 chrome 浏览器中出现某种冻结 - 因为我没有收到任何错误消息,所以我可以触发到达最后一个 for 循环的警报,但是 on.complete 永远不会触发,并且数据库似乎永远不会
函数 e - 的输入是一个读取文件。
我还在 for 循环中对数据执行了操作,但为简单起见,我已将其删除。
function storeDataEnc (e)
var lines = e.target.result.split('\n');
var request = self.indexedDB.open('DB', 1);
request.onerror = function(e)
console.log("there was and error:" +e.target.errorCode);
request.onupgradeneeded = function(e)
var db = request.result;
var store = db.createObjectStore("col1",
keyPath: "col2" );
;
request.onsuccess = function(e)
var db = request.result;
var tx = db.transaction("dataTable", "readwrite");
var store = tx.objectStore("dataTable");
db.onerror = function(e)
console.log("ERROR" + e.target.errorCode);
for (var i = 0; i < lines.length; ++i)
var test = lines.length - 1;
if (i == test) console.log('nearly done');
function forEachLinenow (match)
if ( match.charAt( 0 ) != '#' )
match = match.trim();
var fields = match.split('\t');
var col1in = fields[0];
var col2in = fields[3];
store.put( COL1: col1in, COL2: col2in
forEachLinenow(lines[i] + '\n');
tx.oncomplete = function()
db.close();
alert("all data read");
我猜我不了解浏览器的某些问题,以阻止恶意应用占用过多资源。有没有人使用过这种大小的数据,谁能发现我的过程中的错误。
我的猜测是我可能需要生成多个交易,我确实尝试过,但似乎并没有改变我的问题。
我知道这可能会很慢,但是只要数据成功导入,速度本身并不是最大的问题。
【问题讨论】:
有一点代码味道,你肯定没有理由需要将 1M 记录加载到浏览器数据库中吗? 哈哈 这是一个小众应用程序,从用户的角度来看,它对于包括我在内的少数用户来说非常有用。最后,我可能不得不保留您可能会推荐的服务器端,但是当百万条记录只有 20MB 时,我真的认为大小问题对于小用户组的实际利益来说是非常疏忽的——尤其是考虑到可比较的说一个小视频的大小。 【参考方案1】:您可能会达到浏览器的数据大小限制。
在 mozilla 文档中,它提到了限制 https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria
这里有一些更多的 indexeddb 限制,由 google 记录,用于流行的浏览器。 https://developers.google.com/web/fundamentals/instant-and-offline/web-storage/offline-for-pwa
似乎限制都是基于主机操作系统的可用存储。 检查您希望导入的数据大小和可用存储空间。
【讨论】:
看起来问题实际上是达到了数据大小限制。我没有注意到这一点,因为我预计 indexedDB 将分配 6% 的磁盘空间,如文档中所写,但是在我的 chrome 浏览器中,它最多只允许 101MB。我不确定为什么浏览器会强制执行此限制。此外,有趣的是,与文件相比,该文件在数据库中占用了更多的存储空间。这可能是个问题。 问题确实是应用程序达到了大小限制,但没有引发任何类型的错误处理事件。事实证明这是浏览器选择的问题。当我使用谷歌浏览器并期望总可用存储空间的 6% 时,我的浏览器默认为“隐身模式”,结果证明对应用程序设置了不同的硬限制。使用 Google Chrome 中的开发工具检查选项,我能够看到应用程序中每个窗口的数据限制都设置为 101MB,这是问题所在。 因此,如果其他人遇到类似的问题,这似乎是一个非常简单的浏览器选择和设置问题。确保您没有通过隐身模式运行 indexedDb 应用程序。以上是关于如何有效地将大文件加载到 IndexedDB 存储中?我的应用程序在超过 100,000 行时崩溃的主要内容,如果未能解决你的问题,请参考以下文章
如何有效地将大字符串从 Python 传递到 C++ 扩展方法?