C 试图将2GB写入文件,但看到写入的数量不正确
我试图使用pwrite将2GB写入一个文件,但下面的代码写入的量较小。 但是,如果我使用1GB的2个pwrite调用总共写入2GB,那么就可以了 预期文件大小:2147483648字节(2GB),观察到:2147479552 编译为:C 试图将2GB写入文件,但看到写入的数量不正确,c,file-io,posix,C,File Io,Posix,我试图使用pwrite将2GB写入一个文件,但下面的代码写入的量较小。 但是,如果我使用1GB的2个pwrite调用总共写入2GB,那么就可以了 预期文件大小:2147483648字节(2GB),观察到:2147479552 编译为:gcc-Wall test.c-D\u FILE\u OFFSET\u BITS=64-D\u LARGEFILE64\u SOURCE=1-D\u XOPEN\u SOURCE=600 64位Opensuse上的gcc v 4.5.0 这是完整的程序 #inclu
gcc-Wall test.c-D\u FILE\u OFFSET\u BITS=64-D\u LARGEFILE64\u SOURCE=1-D\u XOPEN\u SOURCE=600
64位Opensuse上的gcc v 4.5.0
这是完整的程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
size_t size = 2147483648; //2GB
off_t offset = 0;
int fd;
char *buf = (char*) malloc (size * sizeof(char));
if(buf == NULL)
{
printf("malloc error \n");
exit(-1);
}
if(-1 == (fd = open("/tmp/test.out", O_RDWR|O_CREAT, 0644)))
{
fprintf(stderr, "Error opening file. Exiting..\n");
free(buf);
exit(-1);
}
if(-1 == (pwrite(fd, buf, size, offset)))
{
perror("pwrite error");
free(buf);
exit(-1);
}
free(buf);
return 0;
}
#包括
#包括
#包括
#包括
int main()
{
大小\u t大小=2147483648;//2GB
off_t offset=0;
int-fd;
char*buf=(char*)malloc(size*sizeof(char));
如果(buf==NULL)
{
printf(“malloc错误\n”);
出口(-1);
}
如果(-1==(fd=open(“/tmp/test.out”,O|RDWR | O|u CREAT,0644)))
{
fprintf(stderr,“打开文件时出错。正在退出..\n”);
免费(buf);
出口(-1);
}
if(-1==(pwrite(fd、buf、size、offset)))
{
perror(“pwrite错误”);
免费(buf);
出口(-1);
}
免费(buf);
返回0;
}
我认为您不仅应该检查pwrite
是否返回-1,还应该检查实际写入的字节数,如果写入的字节数小于您想要写入的字节数,则处理该情况。有关详细信息,请参见pwrite手册页中的:
描述
pwrite()从buf开始,最多可将缓冲区中的字节数写入
偏移量处的文件描述符fd。文件偏移量不正确
变了
返回值
成功时,返回写入的字节数(零)
指示未写入任何内容),或错误时为-1,在这种情况下为errno
设置以指示错误
请注意,pwrite()不需要写入您要求它写入的字节数。它可以写得更少,这不是一个错误。通常,您会在循环中调用pwrite()——如果它没有写入所有数据,或者如果它在errno==EINTR时失败,那么您可以再次调用它来写入其余的数据。您知道是什么使得
pwrite
无法写入所有字节吗?耸耸肩。我不知道,但我能猜到。内核代码中可能存在这样一个点:写入的数量必须适合32位有符号整数。因此,他们必须将其限制为((2^31)-1)字节。因为他们强加了任意的限制,所以确切的值无关紧要,所以他们将其限制为((2^31)-4096)字节,这是4kB页面的总数。这是规范允许的,适当的应用程序将有一个循环,所以它们会很好。(在一个合适的应用程序中,而不是在你发布的玩具示例中,pwrite可以在任何时候被信号中断,所以合适的应用程序需要循环来处理这个问题)。[说清楚,当我将你的代码描述为“玩具示例”时,我并不是指任何不尊重.相反,玩具示例恰恰是在堆栈溢出问题中发布的正确内容-没有人愿意费力地通过数千行“适当的应用程序”来回答问题!]太棒了!这是有道理的(不要担心“玩具示例”:-D)