[英]Simple API for random access into a compressed data file
請推薦適合以下任務的技術。
我有一個相當大的(500MB)數據塊,基本上是一個數字矩陣。 數據熵很低(應該是可以很好地壓縮的)並且存儲位置很昂貴。
我正在尋找的是,使用一個良好的壓縮算法(比如說,GZip)壓縮它,並使用能夠偶爾隨機訪問的標記。 隨機訪問,如“從原始(未壓縮)流中的位置[64位地址]讀取字節”。 這與ZLIB等經典的deflator庫有點不同,它可以讓你連續解壓縮流。 我想要的是,每個字節讀取的延遲,例如,多達1MB的解壓縮工作的隨機訪問。
當然,我希望使用現有的庫而不是重新發明NIH輪。
如果您使用的是Java,我剛剛發布了一個庫: http : //code.google.com/p/jzran 。
字節對編碼允許隨機訪問數據。
你不會得到那么好的壓縮,但你犧牲了一棵樹的自適應(變量)哈希樹,所以你可以訪問它。
但是,您仍然需要某種索引才能找到特定的“字節”。 由於您可以使用1 MB的延遲,因此您將為每1 MB創建一個索引。 希望您能找到一種方法,使您的索引足夠小,仍然可以從壓縮中受益。
此方法的一個好處是隨機訪問編輯。 您可以在相對較小的塊中更新,刪除和插入數據。
如果很少訪問它,您可以使用gzip壓縮索引並在需要時對其進行解碼。
如果您想最大限度地減少所涉及的工作,我只需將數據分成1 MB(或其他)塊,然后將這些塊放入PKZIP存檔中。 然后,您需要一小部分前端代碼來獲取文件偏移量,並除以1M以獲得正確的文件進行解壓縮(顯然,使用余數來獲取該文件中的正確偏移量)。
編輯:是的,現有代碼來處理這個問題。 最新版本的Info-zip解壓縮(6.0是最新版本)包括api.c
除此之外,還包括UzpUnzipToMemory
- 您傳遞ZIP文件的名稱,以及您要檢索的該存檔中某個文件的名稱。 然后,您將獲得一個包含該文件內容的緩沖區。 要進行更新,你需要使用api.c
的api.c,使用ZpInit
和ZpArchive
(盡管這些不像解壓縮方那樣簡單)。
或者,您可以在后台運行zip / unzip副本來完成工作。 這不是很整潔,但實施起來無疑更簡單(如果您願意,還可以讓您輕松切換格式)。
看看我的項目 - csio 。 我認為這正是您正在尋找的:包括類似stdio的接口和多線程壓縮器。
它是用C編寫的庫,它提供CFILE結構和函數cfopen
, cfseek
, cftello
等。 您可以將它與常規(非壓縮)文件和文件一起使用,並在dzip實用程序的幫助下進行壓縮。 該實用程序包含在項目中並使用C ++編寫。 它生成有效的gzip存檔,可以由標准實用程序和csio處理。 dzip可以在很多線程中壓縮(參見-j
選項),因此它可以非常快速地壓縮非常大的文件。
典型用法:
dzip -j4 myfile
...
CFILE file = cfopen("myfile.dz", "r");
off_t some_offset = 673820;
cfseek(file, some_offset);
char buf[100];
cfread(buf, 100, 1, file);
cfclose(file);
它是MIT許可的,因此您可以在您的項目中無限制地使用它。 有關更多信息,請訪問github上的項目頁面: https : //github.com/hoxnox/csio
壓縮算法通常以塊的形式工作,我認為你可以根據塊大小來提出一些東西。
我建議使用Boost Iostreams Library 。 Boost.Iostreams可用於創建訪問TCP連接的流或用作加密和數據壓縮的框架。 該庫包括用於訪問內存映射文件,使用操作系統文件描述符進行文件訪問,用於代碼轉換,用於正則表達式的文本過濾,用於行結束轉換以及用於zlib,gzip和bzip2格式的壓縮和解壓縮的組件。
Boost庫已被C ++標准委員會接受為TR2的一部分,因此最終將內置於大多數編譯器( under std::tr2::sys
)。 它也是跨平台兼容的。
Boost入門指南注意:只有boost::iostreams
某些部分是僅限標題的庫,在鏈接時不需要單獨編譯的庫二進制文件或特殊處理。
如果您需要深度索引,則可以使用BTree算法,“pages”是文件。 在網上存在幾個實現,因為代碼有點棘手。
您可以使用bzip2並根據James Taylor的seek-bzip2輕松制作自己的API
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.