我不断追加到股票报价文件(整数,长整数,双打等)。我用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