我看到了这个post,但我仍然觉得它涉及fseek
,ftell
等等。我还看到了一些其他方法,他们使用feof+fgetc
组合,但他们说{ {1}}不是循环条件的好选择。还有一些人建议使用feof
并逐行阅读,我认为这很乏味。
是否有其他更短的方法来读取整个文件内容?
PS:缩短我的意思是代码行。
答案 0 :(得分:2)
使用mmap()
或自己动手。
大致省略错误检查:
int fd = open(filename, O_RDONLY);
struct stat sb;
fstat(fd, &sb);
char *contents = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
这是文件的只读副本,在内核选择的地址分配。如果您使用的是32位系统,则可能需要担心大于2 GiB的文件。我认为您不能使用fstat()
之类的东西来获取文件大小。如果要增长文件,可以根据POSIX规范指定比文件大小更大的大小。
如果你DIY,那么前三行是相同的。然后你使用:
char *contents = malloc(sb.st_size);
read(fd, contents, sb.st_size);
如前所述,这些示例中省略了所有错误检查;不要在生产就绪代码中冒险。
我开始寻找一些使用mmap()
并发现:
static int sqs_mapfile(const char *file)
{
int fd;
void *vp;
struct stat sb;
if (file == 0)
return(SQS_NOSQSFILE);
if ((fd = open(file, O_RDONLY, 0)) < 0)
return(SQS_OPENFAIL);
if (fstat(fd, &sb) != 0)
{
close(fd);
return(SQS_STATFAIL);
}
vp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
if (vp == MAP_FAILED)
return(SQS_MMAPFAIL);
'SQS_xyz'代码特定于它来自的程序(函数名称也是如此)。此代码使用3参数open()
调用,其中2参数版本就足够了。
答案 1 :(得分:1)
我认为实际工作的最佳方式是这个顺序:
char *buffer;
size_t size;
fseek(your_file, 0, SEEK_END);
size = ftell(your_file);
rewind(your_file);
buffer = malloc(length);
fread(buffer, 1, length, your_file);
当然,你只需要一次:
char *read_file(FILE *file) {
char *buffer;
size_t size;
fseek(your_file, 0, SEEK_END);
size = ftell(your_file);
rewind(your_file);
buffer = malloc(length);
if (buffer) fread(buffer, 1, length, your_file);
return buffer;
}
然后就是:char *file_content = read_file(some_file);