我在内存映射文件的第14章(高级I / O )中测试了APUE中的代码,fstat()
始终返回fdin
的{{1}} 1}}为零,我尝试了st_size
,并得到了相同的结果。我列出了下面的代码(我已经删除了 apue.h 依赖项):
stat()
然后我尝试了Python #include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#define COPYINCR (1024*1024*1024) /* 1GB */
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("usage: %s <fromfile> <tofile>", argv[0]);
exit(1);
}
int fdin, fdout;
if ((fdin = open(argv[1], O_RDONLY)) < 0) {
printf("can not open %s for reading", argv[1]);
exit(1);
}
if ((fdout = open(argv[2] /* typo fix */, O_RDONLY | O_CREAT | O_TRUNC)) < 0) {
printf("can not open %s for writing", argv[2]);
exit(1);
}
struct stat sbuf;
if (fstat(fdin, &sbuf) < 0) { /* need size fo input file */
printf("fstat error");
exit(1);
}
// always zero, and cause truncate error (parameter error)
printf("input_file size: %lld\n", (long long)sbuf.st_size);
if (ftruncate(fdout, sbuf.st_size) < 0) { /* set output file size */
printf("ftruncate error");
exit(1);
}
void *src, *dst;
off_t fsz = 0;
size_t copysz;
while (fsz < sbuf.st_size) {
if (sbuf.st_size - fsz > COPYINCR)
copysz = COPYINCR;
else
copysz = sbuf.st_size - fsz;
if (MAP_FAILED == (src = mmap(0, copysz, PROT_READ,
MAP_SHARED, fdin, fsz))) {
printf("mmap error for input\n");
exit(1);
}
if (MAP_FAILED == (dst = mmap(0, copysz,
PROT_READ | PROT_WRITE,
MAP_SHARED, fdout, fsz))) {
printf("mmap error for output\n");
exit(1);
}
memcpy(dst, src, copysz);
munmap(src, copysz);
munmap(dst, copysz);
fsz += copysz;
}
return 0;
}
,它也得到零结果,为什么会发生这种情况?我尝试了这些并在Mac OS(Darwin内核13.4)和Ubuntu(内核3.13)上得到了相同的结果。
更新:
哦,有一个拼写错误,我应该引用os.stat
到fdout
,而argv[2]
标志肯定会使O_TRUNC
为零。我应该关闭还是删除这个问题?
Python的fdin
也返回os.stat()
的原因是我通过相同的测试文件((stat.st_size == 0)
)进行测试,该文件以前是截断为零(在传递给argv[1]
之前,我没有使用ls -lh
检查其大小),当然os.stat()
返回零。
在你上床睡觉或匆忙之前不要问这些问题。
答案 0 :(得分:0)
好的,真正的问题是双open
个相同的输入文件,这不会导致任何构建或运行时错误,直到ftruncate()
。
第一个open
获取只读fdin
,第二个open
创建一个新文件(fdout
并截断)以从fdin
复制内存映射,第二个打开截断第一个文件(argv[1]
),并清除其所有内容。但是fdin
仍在使用和fstat
(当然),这让我很难找到原因。
第二部分是我总是使用相同的文件进行测试(通过dd
生成)并且没有检查大小,因此os.stat(/path/to/file)
和stat(/path/to/file)
也会返回< / strong> st_size == 0
,这让我相信这必须是一些os-level-prolicy定义的行为,我赶紧去Mac OS(使用相同的拼写错误代码),并得到相同的结果(他们在POSIX级别上确实一致,发生错误!),最后,我来到SO寻求帮助。