我不斷追加到股票報價文件(整數,長整數,雙打等)。我用mmap將這個文件映射到內存中。追加到內存映射文件
將最新附加數據作爲內存映射的一部分提供的最有效方式是什麼?
據我所知,我可以再次打開文件(新文件描述符),然後將其映射到新的數據,但似乎效率低下。另一種建議給我的方法是以1mb的塊預先分配文件,寫入特定的位置直到達到結尾,然後將文件截斷到+ 1mb。
還有其他方法嗎?
Doest Boost對此有幫助嗎?
我不斷追加到股票報價文件(整數,長整數,雙打等)。我用mmap將這個文件映射到內存中。追加到內存映射文件
將最新附加數據作爲內存映射的一部分提供的最有效方式是什麼?
據我所知,我可以再次打開文件(新文件描述符),然後將其映射到新的數據,但似乎效率低下。另一種建議給我的方法是以1mb的塊預先分配文件,寫入特定的位置直到達到結尾,然後將文件截斷到+ 1mb。
還有其他方法嗎?
Doest Boost對此有幫助嗎?
Boost.IOStreams固定大小隻有memory mapped files,所以它不會幫助您的具體問題。 Linux有一個接口mremap
其工作原理如下:
void *new_mapping = mremap(mapping, size, size + GROWTH, MREMAP_MAYMOVE);
if (new_mapping == MAP_FAILED)
// handle error
mapping = new_mapping;
這是不可移植的,但是,(不良記錄)。 Mac OS X似乎沒有mremap
。
在任何情況下,你不需要重新打開該文件時,只需再次munmap
它和mmap
它:
void *append(int fd, char const *data, size_t nbytes, void *map, size_t &len)
{
// TODO: check for errors here!
ssize_t written = write(fd, data, nbytes);
munmap(map, len);
len += written;
return mmap(NULL, len, PROT_READ, 0, fd, 0);
}
預分配方案可能是非常有用的在這裏。請務必跟蹤文件的實際長度並在關閉之前再次截斷它。
看着man page for mremap它應該是可能的。
我知道答案已被接受,但如果我提供答案,它可能會幫助其他人。提前分配一個大文件,例如10 GiB。提前創建其中三個文件,我稱它們爲卷。跟蹤最後一個已知的位置,比如頭文件,另一個文件等,然後從這一點開始追加。如果您達到文件的最大大小並將空間切換到下一個卷。如果沒有更多卷,請創建另一個卷。請注意,您可能會提前完成幾卷,以確保不會阻止附加內容等待創建新卷。這就是我們如何在DVR系統中存儲連續傳入的視頻/音頻進行監控的地方。我們不浪費空間來存儲視頻剪輯的文件名,這就是爲什麼我們不使用真正的文件系統,而是使用平面文件,我們只需跟蹤偏移量,幀信息(幀數,幀類型,寬度/高度等) ),時間記錄和相機頻道。對於你來說,存儲空間對於你正在做的工作來說便宜,而你的時間是非常寶貴的。所以,儘可能多地抓住你想要的時間。你基本上正在實現你自己的文件系統,以滿足你的需求。通用文件系統提供的需求與我們在其他領域需要的需求並不相同。
我的5cents,但他們更具體的C。 製作普通文件,但是mmap尺寸很大 - 例如文件是100K,但是mmap 1GB或更多。然後,您可以安全地訪問所有文件大小。通過文件大小訪問將導致錯誤。 如果你在32位操作系統上,只是不要讓mmap太大,因爲它會佔用你的地址空間。
如果你在Windows上使用boost/iostreams/device/mapped_file.hpp
:
boost::filesystem::resize_file
拋出一個異常,如果讀數映射對象是開放的,由於缺乏共享權限。 而是使用windows-api調整光盤上的文件大小,並且讀取mapped_file
仍然可以打開。
bool resize_file_wapi(string path, __int64 new_file_size) //boost::uintmax_t size
{
HANDLE handle = CreateFile(path.c_str(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
LARGE_INTEGER sz;
sz.QuadPart = new_file_size;
return handle != INVALID_HANDLE_VALUE
&& ::SetFilePointerEx(handle, sz, 0, FILE_BEGIN)
&& ::SetEndOfFile(handle)
&& ::CloseHandle(handle);
}
mremap是Linux專用的,但。 – 2010-12-16 15:16:13