当MMAP()荷兰国际集团的文本文件,就像这样如何解决从mmap()返回的字符串中缺少NUL终止符的问题?
int fd = open("file.txt", O_RDWR);
fstat(fd, &sb)
char *text = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
文件内容被直接映射到存储器中,并text
它将不包含一个NUL - 终止子与正常字符串函数在其上,以便操作不会安全。在Linux上(至少)未使用页面的剩余字节是零填充的,所以在文件大小不是页面大小倍数的所有情况下,您都可以得到NUL终止符。
但依靠感觉脏和其他mmap()
实现(例如,在FreeBSD中,我认为)不会零填充部分页面。映射页面大小倍数的文件也将缺少NUL终止符。
是否有合理的方法来解决这个问题或添加NUL终结符?
事情我已经考虑
- 使用
strn*()
功能完全和跟踪距离的缓冲区的末尾。- 优点:无需NUL终止
- 缺点:需要额外的追踪知道距离解析文本何时结束的文件;一些
str*()
功能没有strn*()
对应,如strstr
。
- 由于建议使用another answer,请在文本文件映射后的固定地址进行匿名映射。
- 优点:可以使用常规的C
str*()
功能 - 缺点:使用
MAP_FIXED
不是线程安全的;看起来像一个可怕的黑客无论如何
- 优点:可以使用常规的C
mmap()
mmap()
一个额外的字节,使地图可写,并写入NUL终止符。 OpenGroup的mmap man page表示,您可以制作比对象大小更大的映射,但访问实际映射对象之外的数据将生成SIGBUS
。- 优点:可以使用常规的C
str*()
功能 - 缺点:(?忽略)需要处理
SIGBUS
,这可能意味着别的事情。我不确定编写NUL终结符会起作用吗?
- 优点:可以使用常规的C
- 将页面大小倍数为
ftruncate()
的文件扩展一个字节。- 优点:可以使用常规的C
str*()
功能;ftruncate()
会为你新分配的区域写入NUL字节 - 缺点:我们必须写入文件,这在所有情况下都是不可能或不可接受的;对于
mmap()
实现不填零
- 优点:可以使用常规的C
- 只是
read()
文件放入一些malloc()
“,忘记了D内存部分页面不能解决问题有关mmap()
- 优点:避免了所有的这些解决方案;为NUL易
malloc()
和额外的字节 - 缺点:比不同的性能特征
mmap()
- 优点:避免了所有的这些解决方案;为NUL易
解决方案#1通常似乎是最好的,只是需要在功能读取的部分一些额外的工作文本。
有更好的选择,还是这些是最好的解决方案?我没有考虑过这些解决方案的哪些方面会使它们更具吸引力?
我的投票是#5。 [KISS](http://en.wikipedia.org/wiki/KISS_principle)。 – 2014-11-24 02:16:42
想想#5。利弊。 mmap需要读取磁盘,所以读取。 Whay是一个骗局吗? BTW +1 @Johnathon Reinhart – 2014-11-24 02:40:10
字符串详细信息:在C中,根据定义,字符串_always_具有终止''\ 0',否则它不是字符串。 'char'数组可能没有''\ 0''。除了命名之外,不会改变你的问题。典型的文本文件没有_any_字符串,但没有文本行。 – chux 2014-11-24 03:10:40