Linux-APUE中对mmap函数的实例中,为什么需要设置输出文件的长度,特别是还调用一个write函数?

发布于 2017-08-26 21:37:22 字数 287 浏览 1125 评论 2

...
...

/* set size of output file */
if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1)
err_sys("lseek error");
if (write(fdout, "", 1) != 1)
err_sys("wrtie error");

...
...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

偏爱自由 2017-10-05 16:54:56

lseek设置offset不会直接使文件变大,还有调用其他函数,见manpage:

Although lseek() may position the file offset beyond the end of the file, this function does not itself extend the size of the file. While the only function in IEEE Std 1003.1-2001 that may directly extend the size of the file is write(), truncate(), and ftruncate(), several functions originally derived from the ISO C standard, such as fwrite(), fprintf(), and so on, may do so (by causing calls on write()).

清晨说ぺ晚安 2017-09-13 07:27:23

其实原因APUE在这个例子前 有说明:

"Since the starting offset of the mapped file is tied to the system's virtual memory page size, what happens if the length of the mapped region isn't a multiple of the page size? Assume that the file size is 12 bytes and that the system's page size is 512 bytes. In this case, the system normally provides a mapped region of 512 bytes, and the final 500 bytes of this region are set to 0. We can modify the final 500 bytes, but any changes we make to them are not reflected in the file. Thus, we cannot append to a file with mmap. We must first grow the file, as we will see in Figure 14.32."

具体到这个例子来说, 如果输入文件比输出文件 长,
比如输入文件内容 ABCDEFG, 输出文件 abcd.
那么如果去掉 lseek/write那两行代码, 则运行程序后, 输出文件 内容 为 ABCD. EFG不会被拷贝到输出文件中.

更新

实际上, 如果仔细看一下APUE的说明的话, 我们可以做一个更有趣的实验.
比如我的freebsd8, page size为4096. 现在 建一个 /tmp/in.txt 大小为4100(大于page size), 建/tmp/out.txt, 大小为10.
重复APUE上面的代码(去掉 lseek/write那两行代码), 得到 Segmentation fault: 11.

按照APUE上来推论, out.txt 的mapped region应该是 一个page size 4096; 向其拷贝4100个字节 导致内存越界了.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文