Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 试图将2GB写入文件,但看到写入的数量不正确_C_File Io_Posix - Fatal编程技术网

C 试图将2GB写入文件,但看到写入的数量不正确

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

我试图使用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

这是完整的程序

#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)