繁体   English   中英

提高mapd_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM