當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