可能重复:
在 C 中获取文件内容的最简单方法
我看到了这篇文章,但我仍然觉得它涉及fseek
等等ftell
。我看到了一些其他使用feof+fgetc
组合的方法,但他们说feof
这不是循环条件的好选择。还有一些人建议fgets
逐行使用和阅读,我认为这很乏味。
还有其他更短的方法来读取整个文件内容吗?
PS:更短的意思是代码行。
可能重复:
在 C 中获取文件内容的最简单方法
我看到了这篇文章,但我仍然觉得它涉及fseek
等等ftell
。我看到了一些其他使用feof+fgetc
组合的方法,但他们说feof
这不是循环条件的好选择。还有一些人建议fgets
逐行使用和阅读,我认为这很乏味。
还有其他更短的方法来读取整个文件内容吗?
PS:更短的意思是代码行。
要么使用,要么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 参数版本就足够了。
我认为有可能实际工作的最短方法是以下顺序:
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);