[英]undefined reference to `boost::iostreams::mapped_file_source::mapped_file_source()'
[英]Boost mapped_file_source, alignment and page size
在性能很重要的情况下,我试图解析一些大小高达几百兆字节的文本文件,因此我使用了boostapped_file_source。 解析器期望源以一个空字节终止,因此我想检查文件大小是否为页面大小的精确倍数(如果是,则使用较慢的非内存映射方法)。 我以为我可以这样做:
if (mf.size() & (mf.alignment() - 1))
但是事实证明,一个测试文件的大小为20480,对齐方式为65536(在Windows 7上为64位),并且程序崩溃了。 我认为这是因为页面大小实际上比对齐的要小,所以我的测试无法正常工作。
如何获得页面大小? 还是我应该做些其他事情? (我需要适用于Windows和Linux的解决方案,愿意在必要时编写系统特定的代码,但在可能的情况下更喜欢可移植的代码。)
最简单的方法似乎是修复解析器,以考虑到输入的结尾(实际上并不太离谱)。
接下来: 一个大警告 。 不确定映射中的尾随字节(如果有)为零是未定义 ¹: http : //pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html
因此,只需使用size + 1映射文件,然后确定性地添加NUL终止符即可 。 我不认为这值得针对平台特定/未定义的行为。
实际上,我刚刚了解了boost::iostreams::mapped_file_base::mapmode::priv
,它非常适合您的需求:
可以写入以私人访问权限打开的文件,但所做的更改不会影响基础文件[ docs ]
这是一个简单的代码段: Live on Coliru
#include <boost/iostreams/device/mapped_file.hpp>
#include <fstream>
#include <iostream>
namespace io = boost::iostreams;
int main() {
// of course, prefer `stat(1)` or `boost::filesystem::file_size()`, but for exposition:
std::streamsize const length = std::distance(std::istreambuf_iterator<char>(std::ifstream("main.cpp").rdbuf()), {});
io::mapped_file mf("main.cpp", io::mapped_file_base::mapmode::priv, length+1);
*(mf.end()-1) = '\0'; // voilà, null termination done, safely, quickly and reliably
std::cout << length << "\n";
std::cout << mf.size() << "\n";
}
替代拼写:
mf.data()[length] = '\0'; // voilà, null termination done, safely, quickly and reliably
*(mf.begin()+length) = 0; // etc.
¹AFAICT可能会杀死兔子或使您的进程崩溃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.