感謝您將您的問題放在這裏在stackoverflow :)這有助於我建立一個開放的知識基礎,爲每個人訪問。
在沒有實例化整個條目的情況下,IndexedDB沒有辦法更新條目。 Dexie添加了update()和modify()方法,但它們只是模擬一種方法來改變某些屬性。在後臺,整個文檔將總是暫時加載到內存中。
IndexedDB也具有Blob支持,但是當存儲在IndexedDB中的Blob中,其整個內容通過規範被克隆/複製到數據庫中。
因此,處理這個問題的最佳方法是爲動態大內容分配一個表併爲其添加新條目。
例如,假設您有一個表「files」和「fileChunks」。您需要不斷增加「文件」,並且每次執行此操作時,都不希望在內存中實例化整個文件。然後,您可以將文件塊作爲單獨的條目添加到fileChunks表中。
let db = new Dexie('filedb');
db.version(1).stores({
files: '++id, name',
fileChunks: '++id, fileId'
});
/** Returns a Promise with ID of the created file */
function createFile (name) {
return db.files.add({name});
}
/** Appends contents to the file */
function appendFileContent (fileId, contentToAppend) {
return db.fileChunks.add ({fileId, chunk: contentToAppend});
}
/** Read entire file */
function readEntireFile (fileId) {
return db.fileChunks.where('fileId').equals(fileId).toArray()
.then(entries => {
return entries.map(entry=>entry.chunk)
.join(''); // join = Assume chunks are strings
});
}
夠簡單。如果你想appendFileContent是滾動緩衝器(用最大的尺寸和擦除舊的內容),您可以添加截斷方法:
function deleteOldChunks (fileId, maxAllowedChunks) {
return db.fileChunks.where('fileId').equals(fileId);
.reverse() // Important, so that we delete old chunks
.offset(maxAllowedChunks) // offset = skip
.delete(); // Deletes all records older before N last records
}
你會得到其他好處,如能夠到尾存儲文件沒有它的全部內容加載到內存中:
/** Tail a file. This function only shows an example on how
* dynamic the data is stored and that file tailing would be
* simple to do. */
function tailFile (fileId, maxLines) {
let result = [], numNewlines = 0;
return db.fileChunks.where('fileId').equals(fileId)
.reverse()
.until(() => numNewLines >= maxLines)
.each(entry => {
result.unshift(entry.chunk);
numNewlines += (entry.chunk.match(/\n/g) || []).length;
})
.then (()=> {
let lines = result.join('').split('\n')
.slice(1); // First line may be cut off
let overflowLines = lines.length - maxLines;
return (overflowLines > 0 ?
lines.slice(overflowLines) :
lines).join('\n');
});
}
我知道塊會在readEntireFile()和tailFile(正確的順序的原因)是IndexedDB的查詢將永遠的順序進行檢索,查詢列主要,但次要按主鍵的順序,這是自動遞增的數字。
這種模式可以用於其他情況下,如日誌記錄等。如果文件不是基於字符串的,你將不得不稍微改變這個例子。具體來說,不要使用string.join()或array.split()。
謝謝你的回覆!我試圖加註你,但由於它是一個新帳戶,所以不會因爲限制而讓我。這就是說,這也是我曾經想到的。基本上只是將文件分塊併爲每個塊添加記錄。我不知道我將如何實現它,但您提供的代碼回答了這個問題。感謝一羣人。愛dexie到目前爲止!我使用它與libmicrohttpd和一個自定義websocket實現,它就像開發一個實際的客戶端應用程序(而不是一個典型的JavaScript應用程序)。愛它! –
謝謝!我更新瞭如何使用滾動緩衝區(截斷舊內容)的答案, –