利用标准IO函数接口实现计算一个本地磁盘某个文件的大小,文件名通过命令行进行传递
利用标准IO函数接口实现计算一个本地磁盘某个文件的大小,文件名通过命令行进行传递
方法一:使用ftell函数直接获取光标偏移量
相关标准库函数
SYNOPSIS
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence); // 设置文件流指针的位置
long ftell(FILE *stream);// 获取当前文件指针相对于文件开头的偏移量
void rewind(FILE *stream);// 将文件指针重置到文件开头,并清除错误标志
int fgetpos(FILE *stream, fpos_t *pos);// 获取文件流的当前位置信息(适用于大文件或复杂定位场景)
int fsetpos(FILE *stream, const fpos_t *pos);// 文件指针定位到fgetpos记录的位置
代码实现
#include <stdio.h>
#include <stdlib.h>
// argc = argv指针数组长度+1
int main(int argc,const char *argv[])
{
// 如果没给文件路径的话报错
if(argc<2) {
printf("请给出文件绝对路径\n");
exit(-1);
}
// 打开文件,用只读方式打开,光标在首个地址
FILE *file = fopen(argv[1],"a");
// 错误处理
if(!file){
perror("文件打开出错");
exit(-1);
}
// ftell计算文件偏移量
long count = ftell(file);
printf("文件的大小是: %ldbytes\n", count * sizeof(char));
// 关闭文件,释放堆内存
fclose(file);
}
方法二:使用fgetc逐字计算
相关标准库函数
SYNOPSIS
#include <stdio.h>
int fgetc(FILE *stream);// 从指定文件流中读取单个字符。每次读取后文件位置指针自动后移一个字节,支持读取文本/二进制文件
char *fgets(char *s, int size, FILE *stream);// 从文件流中读取一行字符串,最多读取size-1个字符(含换行符),末尾自动添加'\0',有效防止缓冲区溢出
int getc(FILE *stream);// 与fgetc()功能相同,但通常通过宏实现,执行效率略高。读取文件流中的单个字符
int getchar(void);// 标准输入(stdin)读取单个字符,等价于fgetc(stdin)
int ungetc(int c, FILE *stream); // 将字符c推回输入流,后续读取操作会优先获取该字符,用于实现"预读"功能
代码实现
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
//1.要求要计算大小的文件的路径需要通过命令行传递给main(),需要判断用户传递的参数是否有效
if (2 != argc)
{
printf("argument is invaild!\n");
exit(1);
}
//2.利用fopen()以只读方式打开需要计算大小的文件 "rb" 以二进制方式打开文件
FILE *fp = fopen(argv[1],"rb");
if (NULL == fp)
{
perror("fopen file error");
exit(1);
}
//3.计算文本数据大小,可以采用循环计数的方式,每次从文本中读取一个字符,直到文本到达末尾
int cnt = 0;
while(1)
{
if( fgetc(fp) == EOF )
{
printf("end of file\n");
break;
}
cnt++;
}
//4.循环终止,则说明计算完成,此时输出文本大小即可
printf("file [%s]: size = %ld \n",argv[1],ftell(fp));
return 0;
}
值得注意的点
这里有个需要注意的点,fopen()需要以“rb”的模式打开文件,r为只读,b为二进制打开。而Linux系统以文本方式打开文件和以二进制方式打开文件的区别:
在Linux系统中,以文本方式打开文件和以二进制方式打开文件的主要区别在于,文本方式可能会对文件内容进行解释和转换,而二进制方式则不会。以文本方式打开文件通常意味着文件会被当作字符数据来处理,而以二进制方式打开文件则会将文件视为字节序列,不对这些字节做任何特殊解释。这种区别对于处理文本文件和二进制文件是重要的,因为二进制文件可能包含可解释为控制字符的字节序列,这会影响文本处理工具的行为。
例如,在某些系统中,文本模式下,字节值小于32(十进制)的字节可能会被解释为控制字符,例如换行符(ASCII码10),而在二进制模式下,这些字节会被视为普通的数据。在编写代码时,如果你需要精确地读取或写入文件中的数据,包括所有的位(比特),那么你应该以二进制方式打开文件。例如,在C语言中,你可以使用 fopen 函数来以文本模式或二进制模式打开文件:
在Linux的man手册中只规定了r,r+,w,w+,a,a+,六种模式,然而,在c语言的C99标准中规定的fopen模式不只六种:
r open text file for reading
w truncate to zero length or create text file for writing
a append; open or create text file for writing at end-of-file
rb open binary file for reading
wb truncate to zero length or create binary file for writing
ab append; open or create binary file for writing at end-of-file
r+ open text file for update (reading and writing)
w+ truncate to zero length or create text file for update
a+ append; open or create text file for update, writing at end-of-file
r+b or rb+ open binary file for update (reading and writing)
w+b or wb+ truncate to zero length or create binary file for update
a+b or ab+ append; open or create binary file for update, writing at end-of-file