您如何确定C中文件的大小?

您如何确定C中文件的大小?

How do you determine the size of a file in C?

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

1
2
3
4
5
#include <stdio.h>

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

基于NilObject的代码:

1
2
3
4
5
6
7
8
9
10
11
#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()打印错误消息,则可以使用以下命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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
"
,
            filename, strerror(errno));

    return -1;
}

在32位系统上,应使用选项-D_FILE_OFFSET_BITS=64对其进行编译,否则,off_t将仅保留最大2 GB的值。有关详细信息,请参见Linux中大文件支持的"使用LFS"部分。


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

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

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

如果您使用的是Windows,则应使用GetFileSizeEx-它实际上使用带符号的64位整数,因此它们将开始遇到8艾字节文件的问题。愚蠢的微软! :-)


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

1
2
3
4
5
6
7
8
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文件,它可能比仅使用平台特定的调用(如GetFileSizeExstat64)慢。


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

Quoting the C99 standard doc that i found online: "Setting the file position indicator to end-of-file, as with fseek(file, 0, SEEK_END), has undefined behavior for a binary stream (because of possible trailing null characters) or for any stream with state-dependent encoding that does not assuredly end in the initial shift state.**

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
}

POSIX

POSIX标准具有自己的获取文件大小的方法。


包括sys/stat.h标头即可使用该功能。

概要

  • 使用stat(3)获取文件统计信息。
  • 获取st_size属性。

例子

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

1
2
3
4
5
6
7
8
9
10
11
12
#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
"
, argv[1], info.st_size);
}
1
2
3
4
5
6
7
8
9
10
11
12
#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
"
, argv[1], info.st_size);
}

ANSI C(标准)

ANSI C没有直接提供确定文件长度的方法。


我们必须要动脑子。现在,我们将使用搜索方法!

概要

  • 使用fseek(3)将文件查找到末尾。
  • 使用ftell(3)获取当前位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
#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);
}

If the file is stdin or a pipe. POSIX, ANSI C won't work.

It will going return 0 if the file is a pipe or stdin.

Opinion:
You should use POSIX standard instead. Because, it has 64bit support.


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


如果您可以使用std c库,则可以:

1
2
3
4
5
6
7
8
#include <sys/stat.h>
off_t fsize(char *file) {
    struct stat filestat;
    if (stat(file, &filestat) == 0) {
        return filestat.st_size;
    }
    return 0;
}

在Google中进行的快速搜索找到了一种使用fseek和ftell的方法,以及一个带有此问题的线程,并给出了答案,它不能用另一种方式仅用C来完成。

您可以使用可移植性库,例如NSPR(为Firefox提供支持的库),也可以检查其实现(相当麻烦)。


尝试这个 -

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

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

file_size包含文件包含的字节数。请注意,由于(根据climits.h)无符号长类型限制为4294967295字节(4 GB),因此,如果您可能要处理更大的文件,则需要查找其他变量类型。


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

1
2
3
4
5
6
7
8
9
10
11
12
//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);

我有一个仅与stdio.h一起使用的函数。 我非常喜欢它,并且效果很好,非常简洁:

1
2
3
4
5
6
7
size_t fsize(FILE *File) {
    size_t FSZ;
    fseek(File, 0, 2);
    FSZ = ftell(File);
    rewind(File);
    return FSZ;
}


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

1
2
3
4
5
6
7
8
9
10
11
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);
    fp.close();
    return
}

看问题,ftell可以轻松获得字节数。

1
2
3
  long size ;
  size = ftell(FILENAME);
  printf("total size is %ld bytes",size);

您可以打开文件,使用以下命令将文件底部相对于偏移量设置为0

1
2
3
#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)

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

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


推荐阅读