无需读取文件即可获取文件大小

时间:2021-08-21 21:42:46

Is there a way to get the size of a file in C without actually reading the file? I know about fseek but as that sets the 'cursor" to the very end of the file, I'm guessing that does actually read through all of the file.

有没有办法在C中获取文件的大小而不实际读取文件?我知道fseek但是因为它将'光标'设置到文件的最末端,我猜这确实读取了所有文件。

Am I wrong making this conclusion? Is there a way to do it?

我做错了这个结论吗?有办法吗?

2 个解决方案

#1


5  

fseek is the portable answer. In any sane implementation, it will read the file's metadata, rather than its content, to determine the end of the file, while refusing to seek in a stream that is not backed by a filesystem that records such data.

fseek是便携式答案。在任何理智的实现中,它将读取文件的元数据而不是其内容,以确定文件的结尾,同时拒绝在没有记录此类数据的文件系统支持的流中进行搜索。

There's no other reliable way to get a file's size in pure ISO C than to seek till the end and then rewind; operating systems have specific APIs to do this, e.g. on a POSIX system you can use fstat on the fileno of the FILE* to get the size:

没有其他可靠的方法来获得纯ISO C中的文件大小,而不是寻找到最后然后倒回;操作系统具有执行此操作的特定API,例如,在POSIX系统上,您可以在FILE *的fileno上使用fstat来获取大小:

#include <sys/types.h>
#include <sys/stat.h>

off_t filesize(FILE *fp)
{
    // error checking omitted for clarity
    int fd = fileno(fp);
    struct stat sb;

    fstat(fd, &sb);
    return sb.st_size;
}

#2


0  

I know about fseek but as that sets the 'cursor" to the very end of the file, I'm guessing that does actually read through all of the file.

我知道fseek但是因为它将'光标'设置到文件的最末端,我猜这确实读取了所有文件。

It does not. For linux, it uses the llseek file operation which will check that the operand is in-range and only set this file descriptor's offset if that check passes. It may need to access the underlying device in order to walk some of the filesystem's data structures, though. But it won't "read" the file in that the operation shouldn't become significantly more expensive with larger files. Technically, that's filesystem-dependent behavior though.

它不是。对于linux,它使用llseek文件操作,它将检查操作数是否在范围内,并且只有在该检查通过时才设置此文件描述符的偏移量。但是,可能需要访问底层设备才能遍历某些文件系统的数据结构。但它不会“读取”该文件,因为对于较大的文件,操作不应该变得更加昂贵。从技术上讲,这是依赖于文件系统的行为。

For posix, you could do the following:

对于posix,您可以执行以下操作:

get_filesize.h:

#include <stdint.h>

uint64_t get_size(const char *filename);

get_filesize_posix.c:

#include "get_filesize.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

uint64_t get_size(const char *filename)
{
    struct stat s;
    int ret = stat(filename, &s);
    if (ret != 0)
        perror("stat");

    return (uint64_t) s.st_size;
}

#1


5  

fseek is the portable answer. In any sane implementation, it will read the file's metadata, rather than its content, to determine the end of the file, while refusing to seek in a stream that is not backed by a filesystem that records such data.

fseek是便携式答案。在任何理智的实现中,它将读取文件的元数据而不是其内容,以确定文件的结尾,同时拒绝在没有记录此类数据的文件系统支持的流中进行搜索。

There's no other reliable way to get a file's size in pure ISO C than to seek till the end and then rewind; operating systems have specific APIs to do this, e.g. on a POSIX system you can use fstat on the fileno of the FILE* to get the size:

没有其他可靠的方法来获得纯ISO C中的文件大小,而不是寻找到最后然后倒回;操作系统具有执行此操作的特定API,例如,在POSIX系统上,您可以在FILE *的fileno上使用fstat来获取大小:

#include <sys/types.h>
#include <sys/stat.h>

off_t filesize(FILE *fp)
{
    // error checking omitted for clarity
    int fd = fileno(fp);
    struct stat sb;

    fstat(fd, &sb);
    return sb.st_size;
}

#2


0  

I know about fseek but as that sets the 'cursor" to the very end of the file, I'm guessing that does actually read through all of the file.

我知道fseek但是因为它将'光标'设置到文件的最末端,我猜这确实读取了所有文件。

It does not. For linux, it uses the llseek file operation which will check that the operand is in-range and only set this file descriptor's offset if that check passes. It may need to access the underlying device in order to walk some of the filesystem's data structures, though. But it won't "read" the file in that the operation shouldn't become significantly more expensive with larger files. Technically, that's filesystem-dependent behavior though.

它不是。对于linux,它使用llseek文件操作,它将检查操作数是否在范围内,并且只有在该检查通过时才设置此文件描述符的偏移量。但是,可能需要访问底层设备才能遍历某些文件系统的数据结构。但它不会“读取”该文件,因为对于较大的文件,操作不应该变得更加昂贵。从技术上讲,这是依赖于文件系统的行为。

For posix, you could do the following:

对于posix,您可以执行以下操作:

get_filesize.h:

#include <stdint.h>

uint64_t get_size(const char *filename);

get_filesize_posix.c:

#include "get_filesize.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

uint64_t get_size(const char *filename)
{
    struct stat s;
    int ret = stat(filename, &s);
    if (ret != 0)
        perror("stat");

    return (uint64_t) s.st_size;
}