首页 文章

如何在C中获取文件大小? [重复]

提问于
浏览
326

可能重复:如何确定C中文件的大小?

如何找出文件的大小?我打开了一个用C编写的应用程序 . 我想知道大小,因为我想把加载文件的内容放入一个字符串,我用 malloc() 分配 . 只是写 malloc(10000*sizeof(char)); 是恕我直言,一个坏主意 .

8 回答

  • -36

    如果您使用的是Linux,请认真考虑使用glib中的g_file_get_contents函数 . 它处理加载文件,分配内存和处理错误的所有代码 .

  • 8

    如果您有文件描述符 fstat() 则返回包含文件大小的stat结构 .

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    // fd = fileno(f); //if you have a stream (e.g. from fopen), not a file descriptor.
    struct stat buf;
    fstat(fd, &buf);
    off_t size = buf.st_size;
    
  • 9

    您需要寻找文件的末尾然后询问位置:

    fseek(fp, 0L, SEEK_END);
    sz = ftell(fp);
    

    然后你可以回头,例如:

    fseek(fp, 0L, SEEK_SET);
    

    或者(如果想要开始)

    rewind(fp);
    
  • 2

    如何使用 lseek / fseek / stat / fstat 获取文件大小?

    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    
    
    void
    fseek_filesize(const char *filename)
    {
        FILE *fp = NULL;
        long off;
    
        fp = fopen(filename, "r");
        if (fp == NULL)
        {
            printf("failed to fopen %s\n", filename);
            exit(EXIT_FAILURE);
        }
    
        if (fseek(fp, 0, SEEK_END) == -1)
        {
            printf("failed to fseek %s\n", filename);
            exit(EXIT_FAILURE);
        }
    
        off = ftell(fp);
        if (off == (long)-1)
        {
            printf("failed to ftell %s\n", filename);
            exit(EXIT_FAILURE);
        }
    
        printf("[*] fseek_filesize - file: %s, size: %ld\n", filename, off);
    
        if (fclose(fp) != 0)
        {
            printf("failed to fclose %s\n", filename);
            exit(EXIT_FAILURE);
        }
    }
    
    void
    fstat_filesize(const char *filename)
    {
        int fd;
        struct stat statbuf;
    
        fd = open(filename, O_RDONLY, S_IRUSR | S_IRGRP);
        if (fd == -1)
        {
            printf("failed to open %s\n", filename);
            exit(EXIT_FAILURE);
        }
    
        if (fstat(fd, &statbuf) == -1)
        {
            printf("failed to fstat %s\n", filename);
            exit(EXIT_FAILURE);
        }
    
        printf("[*] fstat_filesize - file: %s, size: %lld\n", filename, statbuf.st_size);
    
        if (close(fd) == -1)
        {
            printf("failed to fclose %s\n", filename);
            exit(EXIT_FAILURE);
        }
    }
    
    void
    stat_filesize(const char *filename)
    {
        struct stat statbuf;
    
        if (stat(filename, &statbuf) == -1)
        {
            printf("failed to stat %s\n", filename);
            exit(EXIT_FAILURE);
        }
    
        printf("[*] stat_filesize - file: %s, size: %lld\n", filename, statbuf.st_size);
    
    }
    
    void
    seek_filesize(const char *filename)
    {
        int fd;
        off_t off;
    
        if (filename == NULL)
        {
            printf("invalid filename\n");
            exit(EXIT_FAILURE);
        }
    
        fd = open(filename, O_RDONLY, S_IRUSR | S_IRGRP);
        if (fd == -1)
        {
            printf("failed to open %s\n", filename);
            exit(EXIT_FAILURE);
        }
    
        off = lseek(fd, 0, SEEK_END);
        if (off == (off_t)-1)
        {
            printf("failed to lseek %s\n", filename);
            exit(EXIT_FAILURE);
        }
    
        printf("[*] seek_filesize - file: %s, size: %lld\n", filename, off);
    
        if (close(fd) == -1)
        {
            printf("failed to close %s\n", filename);
            exit(EXIT_FAILURE);
        }
    }
    
    int
    main(int argc, const char *argv[])
    {
        int i;
    
        if (argc < 2)
        {
            printf("%s <file1> <file2>...\n", argv[0]);
            exit(0);
        }
    
        for(i = 1; i < argc; i++)
        {
            seek_filesize(argv[i]);
            stat_filesize(argv[i]);
            fstat_filesize(argv[i]);
            fseek_filesize(argv[i]);
        }
    
        return 0;
    }
    
  • 99
    #include <stdio.h>
    
    #define MAXNUMBER 1024
    
    int main()
    {
        int i;
        char a[MAXNUMBER];
    
        FILE *fp = popen("du -b  /bin/bash", "r");
    
        while((a[i++] = getc(fp))!= 9)
            ;
    
        a[i] ='\0';
    
        printf(" a is %s\n", a);
    
        pclose(fp);
        return 0;
    }
    

    HTH

  • 334

    您是否考虑过不计算文件大小而只是在必要时增加数组?这是一个示例(省略错误检查):

    #define CHUNK 1024
    
    /* Read the contents of a file into a buffer.  Return the size of the file 
     * and set buf to point to a buffer allocated with malloc that contains  
     * the file contents.
     */
    int read_file(FILE *fp, char **buf) 
    {
      int n, np;
      char *b, *b2;
    
      n = CHUNK;
      np = n;
      b = malloc(sizeof(char)*n);
      while ((r = fread(b, sizeof(char), CHUNK, fp)) > 0) {
        n += r;
        if (np - n < CHUNK) { 
          np *= 2;                      // buffer is too small, the next read could overflow!
          b2 = malloc(np*sizeof(char));
          memcpy(b2, b, n * sizeof(char));
          free(b);
          b = b2;
        }
      }
      *buf = b;
      return n;
    }
    

    这样做的优点是即使对于无法获得文件大小的流(例如stdin)也能工作 .

  • 13

    使用标准库:

    假设您的实现有意义地支持SEEK_END:

    fseek(f, 0, SEEK_END); // seek to end of file
    size = ftell(f); // get current file pointer
    fseek(f, 0, SEEK_SET); // seek back to beginning of file
    // proceed with allocating memory and reading the file
    

    Linux / POSIX:

    您可以使用 stat (如果您知道文件名)或 fstat (如果您有文件描述符) .

    以下是stat的示例:

    #include <sys/stat.h>
    struct stat st;
    stat(filename, &st);
    size = st.st_size;
    

    Win32:

    您可以使用GetFileSizeGetFileSizeEx .

  • 430

    我最后只是做了一个简短而又甜蜜的 fsize 函数(注意,没有错误检查)

    int fsize(FILE *fp){
        int prev=ftell(fp);
        fseek(fp, 0L, SEEK_END);
        int sz=ftell(fp);
        fseek(fp,prev,SEEK_SET); //go back to where we were
        return sz;
    }
    

    它's kind of silly that the standard C library doesn'有这样的功能,但我可以看出为什么它很难,因为不是每个_523701都有一个大小(例如 /dev/null

相关问题