利用标准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

posted @ 2025-03-19 00:46  小镇青年达师傅  阅读(258)  评论(0)    收藏  举报