在C中以最短的方式(并且无忧无虑地)读取整个文件内容

时间:2012-04-19 19:34:44

标签: c file

  

可能重复:
  Easiest way to get file's contents in C

我看到了这个post,但我仍然觉得它涉及fseekftell等等。我还看到了一些其他方法,他们使用feof+fgetc组合,但他们说{ {1}}不是循环条件的好选择。还有一些人建议使用feof并逐行阅读,我认为这很乏味。

是否有其他更短的方法来读取整个文件内容?

PS:缩短我的意思是代码行。

2 个答案:

答案 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);