154

如何计算文件的大小(以字节为单位)?

#include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}
4

14 回答 14

164

在类 Unix 系统上,您可以使用 POSIX 系统调用:stat在路径上,或fstat在已经打开的文件描述符(POSIX手册页,Linux手册页)上。(从或在 stdio 流上
获取文件描述符)。open(2)fileno(FILE*)

基于 NilObject 的代码:

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

off_t fsize(const char *filename) {
    struct stat st; 

    if (stat(filename, &st) == 0)
        return st.st_size;

    return -1; 
}

变化:

  • 将文件名参数设为const char.
  • 更正了struct stat缺少变量名称的定义。
  • 返回-1错误而不是0,这对于空文件来说是模棱两可的。off_t是有符号类型,所以这是可能的。

如果要fsize()打印错误消息,可以使用以下命令:

#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

off_t fsize(const char *filename) {
    struct stat st;

    if (stat(filename, &st) == 0)
        return st.st_size;

    fprintf(stderr, "Cannot determine size of %s: %s\n",
            filename, strerror(errno));

    return -1;
}

在 32 位系统上,您应该使用选项编译它-D_FILE_OFFSET_BITS=64,否则off_t最多只能保存 2 GB 的值。有关详细信息,请参阅Linux中的大文件支持的“使用 LFS”部分。

于 2008-08-12T00:55:48.313 回答
79

不要使用int. 如今,大小超过 2 GB 的文件很常见

不要使用unsigned int. 大小超过 4 GB 的文件很常见,因为一些不太常见的污垢

IIRC 标准库定义off_t为无符号 64 位整数,这是每个人都应该使用的。几年后,当我们开始有 16 个 EB 文件时,我们可以将其重新定义为 128 位。

如果你在 Windows 上,你应该使用GetFileSizeEx - 它实际上使用一个有符号的 64 位整数,所以他们会开始遇到 8 个 exabyte 文件的问题。愚蠢的微软!:-)

于 2008-08-11T22:09:03.907 回答
32

马特的解决方案应该可以工作,除了它是 C++ 而不是 C,而且最初的告诉不应该是必要的。

unsigned long fsize(char* file)
{
    FILE * f = fopen(file, "r");
    fseek(f, 0, SEEK_END);
    unsigned long len = (unsigned long)ftell(f);
    fclose(f);
    return len;
}

也为你修好了牙套。;)

更新:这并不是最好的解决方案。它在 Windows 上限制为 4GB 文件,并且可能比仅使用特定于平台的调用(如GetFileSizeExor stat64.

于 2008-08-11T21:26:15.493 回答
14

**不要这样做(为什么?):

引用我在网上找到的 C99 标准文档:“将文件位置指示符设置为文件结尾,fseek(file, 0, SEEK_END)与这并不一定会以初始换档状态结束。**

将定义更改为 int 以便可以传输错误消息,然后使用fseek()andftell()来确定文件大小。

int fsize(char* file) {
  int size;
  FILE* fh;

  fh = fopen(file, "rb"); //binary mode
  if(fh != NULL){
    if( fseek(fh, 0, SEEK_END) ){
      fclose(fh);
      return -1;
    }

    size = ftell(fh);
    fclose(fh);
    return size;
  }

  return -1; //error
}
于 2008-08-11T21:28:05.737 回答
10

POSIX

POSIX标准有自己的方法来获取文件大小 。
包括sys/stat.h标题以使用该功能。

概要

  • 使用 获取文件统计信息stat(3)
  • 获得st_size财产。

例子

注意:它将大小限制为4GB. 如果不是Fat32文件系统,则使用 64 位版本!

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

int main(int argc, char** argv)
{
    struct stat info;
    stat(argv[1], &info);

    // 'st' is an acronym of 'stat'
    printf("%s: size=%ld\n", argv[1], info.st_size);
}
#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char** argv)
{
    struct stat64 info;
    stat64(argv[1], &info);

    // 'st' is an acronym of 'stat'
    printf("%s: size=%ld\n", argv[1], info.st_size);
}

ANSI C(标准)

ANSI C不直接提供确定文件长度的方法 。
我们将不得不使用我们的头脑。现在,我们将使用 seek 方法!

概要

例子

#include <stdio.h>

int main(int argc, char** argv)
{
    FILE* fp = fopen(argv[1]);
    int f_size;

    fseek(fp, 0, SEEK_END);
    f_size = ftell(fp);
    rewind(fp); // to back to start again

    printf("%s: size=%ld", (unsigned long)f_size);
}

如果文件是stdin或管道。POSIX,ANSI C不起作用。
如果0文件是管道或stdin.

意见:您应该改用POSIX标准。因为,它支持 64 位。

于 2019-01-09T16:48:40.423 回答
4

如果您可以使用 std c 库:

#include <sys/stat.h>
off_t fsize(char *file) {
    struct stat filestat;
    if (stat(file, &filestat) == 0) {
        return filestat.st_size;
    }
    return 0;
}
于 2008-08-11T21:21:42.850 回答
4

如果您正在构建 Windows 应用程序,请使用GetFileSizeEx API,因为 CRT 文件 I/O 很混乱,尤其是在确定文件长度时,由于不同系统上文件表示的特殊性;)

于 2008-08-12T00:15:35.853 回答
3

我找到了一种使用 fseek 和 ftell 的方法,以及一个带有这个问题的线程,其中的答案不能仅在 C 中以另一种方式完成。

您可以使用像NSPR(支持 Firefox 的库)这样的可移植库。

于 2008-08-11T21:30:08.353 回答
2

我使用这组代码来查找文件长度。

//opens a file with a file descriptor
FILE * i_file;
i_file = fopen(source, "r");

//gets a long from the file descriptor for fstat
long f_d = fileno(i_file);
struct stat buffer;
fstat(f_d, &buffer);

//stores file size
long file_length = buffer.st_size;
fclose(i_file);
于 2014-02-08T01:54:26.347 回答
0

从 Windows 文件详细信息中提取的C++ MFC,不确定这是否比搜索性能更好,但如果它是从元数据中提取的,我认为它更快,因为它不需要读取整个文件

ULONGLONG GetFileSizeAtt(const wchar_t *wFile)
{
    WIN32_FILE_ATTRIBUTE_DATA fileInfo;
    ULONGLONG FileSize = 0ULL;
    //https://docs.microsoft.com/nl-nl/windows/win32/api/fileapi/nf-fileapi-getfileattributesexa?redirectedfrom=MSDN
    //https://docs.microsoft.com/nl-nl/windows/win32/api/fileapi/ns-fileapi-win32_file_attribute_data?redirectedfrom=MSDN
    if (GetFileAttributesEx(wFile, GetFileExInfoStandard, &fileInfo))
    {
        ULARGE_INTEGER ul;
        ul.HighPart = fileInfo.nFileSizeHigh;
        ul.LowPart = fileInfo.nFileSizeLow;
        FileSize = ul.QuadPart;
    }
    return FileSize;
}
于 2022-01-09T17:02:18.263 回答
-1

试试这个 -

fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);

这首先是寻找文件的末尾;然后,报告文件指针的位置。最后(这是可选的)它倒回到文件的开头。注意fp应该是二进制流。

file_size 包含文件包含的字节数。请注意,由于(根据 climits.h)unsigned long 类型被限制为 4294967295 字节(4 GB),如果您可能要处理比这更大的文件,则需要找到不同的变量类型。

于 2016-12-29T21:45:44.540 回答
-1

我有一个仅适用于stdio.h. 我非常喜欢它,它工作得很好而且非常简洁:

size_t fsize(FILE *File) {
    size_t FSZ;
    fseek(File, 0, 2);
    FSZ = ftell(File);
    rewind(File);
    return FSZ;
}
于 2019-07-11T22:22:44.803 回答
-2

这是一个返回文件大小的简单而干净的函数。

long get_file_size(char *path)
{
    FILE *fp;
    long size = -1;
    /* Open file for reading */
    fp = fopen(path, "r");
    fseek(fp, 0, SEEK_END);
    size = ftell(fp); 
    fclose(fp);
    return 
}
于 2016-06-06T15:27:52.440 回答
-3

您可以打开文件,使用相对于文件底部的 0 偏移量

#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)  

fseek 返回的值是文件的大小。

我很长时间没有用 C 编写代码,但我认为它应该可以工作。

于 2008-08-11T21:23:59.787 回答