我怎样才能知道我用C语言编写的应用程序打开的文件的大小? 我想知道大小,因为我想把加载文件的内容放入一个字符串,我使用malloc()分配。正在写入malloc(10000*sizeof(char));恕我直言,这是个坏主意。


当前回答

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

其他回答

如果有文件描述符,fstat()返回一个包含文件大小的统计结构。

#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;

您是否考虑过不计算文件大小,只在必要时增大数组?下面是一个例子(省略了错误检查):

#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)也可以工作。

使用标准库:

假设你的实现有意义地支持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:

您可以使用GetFileSize或GetFileSizeEx。

我最终只是做了一个简短而甜蜜的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;
}

标准C库没有这样的函数,这有点愚蠢,但我可以看到为什么它会很困难,因为不是每个“文件”都有大小(例如/dev/null)。

你需要搜索到文件的末尾,然后请求位置:

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

然后你可以回头寻找,例如:

fseek(fp, 0L, SEEK_SET);

或者(如果你想从头开始)

rewind(fp);