zha*_*tar 14 c linux file-io posix unbuffered
这是我的问题的描述:
我想读取一个大的文件,大约6.3GB,所有内存使用readC中的系统调用,但发生错误.这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
int main(int argc, char* argv[]) {
int _fd = open(argv[1], O_RDONLY, (mode_t) 0400);
if (_fd == -1)
return 1;
off_t size = lseek(_fd, 0, SEEK_END);
printf("total size: %lld\n", size);
lseek(_fd, 0, SEEK_SET);
char *buffer = malloc(size);
assert(buffer);
off_t total = 0;
ssize_t ret = read(_fd, buffer, size);
if (ret != size) {
printf("read fail, %lld, reason:%s\n", ret, strerror(errno));
printf("int max: %d\n", INT_MAX);
}
}
Run Code Online (Sandbox Code Playgroud)
并编译它:
gcc read_test.c
Run Code Online (Sandbox Code Playgroud)
然后运行:
./a.out bigfile
Run Code Online (Sandbox Code Playgroud)
输出:
total size: 6685526352
read fail, 2147479552, reason:Success
int max: 2147483647
Run Code Online (Sandbox Code Playgroud)
系统环境是
3.10.0_1-0-0-8 #1 SMP Thu Oct 29 13:04:32 CST 2015 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
有两个地方我不明白:
errno也没有正确设置.chq*_*lie 14
由于read多种原因,系统调用可以返回小于请求大小的数字,正非零返回值不是错误,errno在这种情况下未设置,其值是不确定的.您应该继续读取循环,直到read返回0文件结尾或-1错误.这是一个非常常见的错误,依赖于read在单个调用中读取完整的块,甚至是常规文件.使用fread更简单的语义.
您打印的值INT_MAX与您的问题无关.大小off_t和size_t有趣的.在你的平台上,64位GNU/Linux的,你是幸运的,无论off_t和size_t是64位长. ssize_t具有与size_t定义相同的大小.在其他64位平台上,off_t可能小于size_t,阻止正确评估文件大小,或者size_t可能小于off_t,让malloc分配小于文件大小的块.请注意,在这种情况下,read将传递相同的较小大小,因为size在两个调用中都会被静默截断.
如果它返回-1,你应该只对读取保释.从手册页:
成功时,返回读取的字节数(零表示文件结束),文件位置按此编号提前.如果此数字小于请求的字节数,则不是错误;
我的猜测是,在文件系统的2G边界,a read()可以读取一个短缓冲区.