-2

可能重复:
在 C 中获取文件内容的最简单方法

我看到了这篇文章,但我仍然觉得它涉及fseek等等ftell。我看到了一些其他使用feof+fgetc组合的方法,但他们说feof这不是循环条件的好选择。还有一些人建议fgets逐行使用和阅读,我认为这很乏味。

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

PS:更短的意思是代码行。

4

2 回答 2

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 参数版本就足够了。

于 2012-04-19T19:36:30.513 回答
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);

于 2012-04-19T19:48:24.407 回答