如何计算文件的大小(以字节为单位)?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
在类 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”部分。
不要使用int
. 如今,大小超过 2 GB 的文件很常见
不要使用unsigned int
. 大小超过 4 GB 的文件很常见,因为一些不太常见的污垢
IIRC 标准库定义off_t
为无符号 64 位整数,这是每个人都应该使用的。几年后,当我们开始有 16 个 EB 文件时,我们可以将其重新定义为 128 位。
如果你在 Windows 上,你应该使用GetFileSizeEx - 它实际上使用一个有符号的 64 位整数,所以他们会开始遇到 8 个 exabyte 文件的问题。愚蠢的微软!:-)
马特的解决方案应该可以工作,除了它是 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 文件,并且可能比仅使用特定于平台的调用(如GetFileSizeEx
or stat64
.
**不要这样做(为什么?):
引用我在网上找到的 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
}
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不直接提供确定文件长度的方法
。
我们将不得不使用我们的头脑。现在,我们将使用 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 位。
如果您可以使用 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;
}
如果您正在构建 Windows 应用程序,请使用GetFileSizeEx API,因为 CRT 文件 I/O 很混乱,尤其是在确定文件长度时,由于不同系统上文件表示的特殊性;)
我找到了一种使用 fseek 和 ftell 的方法,以及一个带有这个问题的线程,其中的答案不能仅在 C 中以另一种方式完成。
您可以使用像NSPR(支持 Firefox 的库)这样的可移植库。
我使用这组代码来查找文件长度。
//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);
从 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;
}
试试这个 -
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
这首先是寻找文件的末尾;然后,报告文件指针的位置。最后(这是可选的)它倒回到文件的开头。注意fp
应该是二进制流。
file_size 包含文件包含的字节数。请注意,由于(根据 climits.h)unsigned long 类型被限制为 4294967295 字节(4 GB),如果您可能要处理比这更大的文件,则需要找到不同的变量类型。
我有一个仅适用于stdio.h
. 我非常喜欢它,它工作得很好而且非常简洁:
size_t fsize(FILE *File) {
size_t FSZ;
fseek(File, 0, 2);
FSZ = ftell(File);
rewind(File);
return FSZ;
}
这是一个返回文件大小的简单而干净的函数。
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
}
您可以打开文件,使用相对于文件底部的 0 偏移量
#define SEEKBOTTOM 2
fseek(handle, 0, SEEKBOTTOM)
fseek 返回的值是文件的大小。
我很长时间没有用 C 编写代码,但我认为它应该可以工作。