如何在 Linux 上获取 C 中的文件长度?

How to get the file length in C on Linux?

我正在寻找 Linux 中 Microsoft _filelength 的等效项。我试过了,但是不正确。

long _filelength(char *f)
{
    struct stat st;
    stat(f, &st);
    return st.st_size;
}

if((hfile = fopen("data.arp","rb"))!=NULL)
    fsize = _filelength(fileno(hfile));

如何在 Linux 上获取 C 中的文件长度?

I'm looking for the equivalent of _filelength in linux.

这是一种非常错误的方法,表明了错误的心态。 在 Linux 上没有 Windows' _filelength 的确切等价物。 Linux 是 而不是 Windows 而 Windows 不是 Linux。每个操作系统都有自己的 API and its own vision of files (On Linux, they are inodes, see inode(7) and also this answer...), processes etc.... Linux is mostly POSIX compliant, so study POSIX and read some book on Linux system programming, perhaps the old ALP or something newer. Don't expect (and don't even try) to find an equivalent of every Windows or WinAPI function on Linux. See intro(2), syscalls(2), intro(3).

仔细阅读stat(2). It takes a string (some file path), not a file descriptor (like fstat does) as the one given by fileno(3). It can fail (and you need to understand why, probably using errno(3),这绝不是负面的)。

顺便说一句,名称以 _ 开头的标识符是保留的。

也许你可以试试:

long filelength(const char*filpath) { // don't use that. Learn POSIX API
   struct stat st;
   if (stat(filpath, &st)) /*failure*/
      return -1; // when file does not exist or is not accessible
   return (long) st.st_size;
}

但实际上你最好直接在你的程序中使用 stat(并且 在失败时检查 errno(3),而不是像简单地返回 -1我在上面做了),你可能应该在其中使用 stat 返回的 other 元数据。

Linux(和 Unix)也有 sparse files, hard links, device files, symbolic links, anonymous files (e.g. still opened inodes, but no more present in the file system), fifo(7)-s, unix(7) 套接字,等等......你可能需要处理它们(但它们在 Windows 上没有完全等价的东西).

另读Operating Systems: Three Easy Pieces

您可能会使用多平台框架,例如 Poco or Boost or Qt. They are trying to provide some common abstraction above several operating systems (but some details still matter and are difficult to hide or to abstract; for example a file path is not the same on Windows and on Linux. See path_resolution(7)...)

您应该使用所有警告和调试信息进行编译(因此 gcc -Wall -Wextra -gGCC). Then use the gdb debugger. You might also use strace(1) to understand the system calls 由您的程序完成。

你必须通过文件查找。

fseek(file, 0L, SEEK_END);

然后获取当前位置:

fileSize = ftell(file);

然后将位置重置回开始使用:

rewind(file);
FILE *fp = fopen("filename", "rb");
fseek(fp, 0, SEEK_END);
int lengthOfFile = ftell(fp);
fclose(fp);

也许你可以试试这个。

size_t _filelength(int filedes)
{
    off_t pos = lseek(filedes, 0, SEEK_CUR);
    if (pos != (off_t)-1)
    {
        off_t size = lseek(filedes, 0, SEEK_END);
        lseek(filedes, pos, SEEK_SET);
        return (size_t)size;
    }
    return (off_t)-1;
}