【Linux学习】文件系统 - 第一篇


🍑个人主页:Jupiter. 🚀 所属专栏:Linux从入门到进阶 欢迎大家点赞收藏评论😊

📕文章目录

📚基础知识铺垫

文件由文件属性与文件内容构成,所以空文件也会占用空间的,因为有文件属性。文件=文件内容+属性

对文件进行操作的时候,都是通过执行代码的方式完成操作,操作必须先将文件打开,打开文件的目的就是将文件从磁盘加载到内存。(内存级文件,没有打开的就在磁盘)

是谁打开文件呢?是进程在打开(这个很好理解,不赘述)。注意:一个进程可以打开多个文件。

在一定时间内,系统中存在多个进程,同时可能存在更多的被打开的文件,OS系统会管理这些文件,先描述,再组织。后续文章会具体讲解OS怎么管理的。


🍑重新使用C语言文件接口---对比重定向

🎈fopen函数


简单介绍:

参数一:需要打开的文件路径。

参数二:是以哪种方式打开。

打开方式选项的介绍:

选项 打开方式 注意事项
r 以只读的方式打开 文件不存在,则打开失败,返回NULL
r+ 以读写的方式打开 文件不存在,则打开失败,返回NULL
w 以只写的方式打开 文件不存在,则创建文件,返回文件的指针 ,每次写之前会将文件清空
w+ 以读写方式打开 文件不存在,则创建文件,返回文件的指针 ,每次写之前会将文件清空
a 以追加写的方式打开 文件不存在,则创建文件,返回文件的指针 ,不会清空,在文件末尾追加的方式写
a+ 以读与追加写的方式打开 文件不存在,则创建文件,返回文件的指针 ,不会清空,在文件末尾追加的方式写

我们可以发现,指令> 与 >>选项w和a有类似的效果。输出与追加重定向的本质就是向文件里面写入,向文件里面写入需要先打开文件,这里猜测输出重定向之前文件要以w的方式打开,所以会先被清空,而追加重定向是以a的方式打开。


补充知识

以w等其他方式打开,如果文件不存在,则会在当前目录下建立一个文件。

那什么叫做当前目录呢?

  • 上一篇自定以shell里面已经知道了进程的当前路径可以通过环境变量来获取,这里介绍一个新的方法:通过指令ls查看文件 ./proc/进程编号 来查看,其中cwd即使当前目录。如图所示:

其中可以使用该函数chdir来改变当前工作路径,使新建文件建立在指令路径中,上一篇文章讲过,这里不再赘述。


向文件中写操作的接口很多,比如fwrite,fputs,puts....

简单介绍几个:

🌏fputs


简单介绍:

参数一:是一个字符串,想要写进文件的内容。

参数二:是想写进哪一个文件。

代码示例:

cpp 复制代码
int main()
{
     FILE* fp = fopen("log.txt","w");
     if(fp==NULL)
     {
         perror("fopen");
     }
     const char* msg="hello fputs";
     fputs(msg,fp);
 
     fclose(fp);
 }

🌙fwrite


简单介绍:

参数一:要写入的字符串。

参数二:写入基本单元的大小。

参数三:要写多少个基本单元。

参数四:写进哪一个文件。

如果成功就返回写的数据块的个数,失败就返回0。

示例代码:

cpp 复制代码
 int main()                                        
 {                                                 
     FILE* fp = fopen("log.txt","w");              
     if(fp==NULL)                                  
     {                                             
         perror("fopen");                          
     }                                             
     const char* msg="hello fputs";                
     //fputs(msg,fp);                              
     size_t n = fwrite(msg,strlen(msg),1,fp);    //n=1
     //size_t n = fwrite(msg,1,strlen(msg),fp);  //n=strlen(msg)
     printf("%d\n",n);                                                                                                                 
                                                                          
     fclose(fp);                                                          
     return 0;                                                            
 }                    

介绍几个读文件的接口:

🚀fread(一次全部读取)


简单介绍:

参数一:读出来的内容放到ptr字符串中。

参数二:读的基本单元的大小。

参数三:要读多少个基本单元。

参数四:从哪一个文件读。

返回值:如果成功就返回写的数据块的个数,失败就返回0。

代码示例:

cpp 复制代码
 int main()
 {
     FILE* fp = fopen("log.txt","r");
     if(fp==NULL)
     {
         perror("fopen");
     }
     char* msg;                                                                                                                             						               
     size_t n = fread(msg,strlen(msg),1,fp);  //n=1
     printf("%d\n",n);
 
     fclose(fp);
     return 0;
 }

🔍fgets(按行读取)


简单介绍:

参数一:读取的内容放在哪里。

参数二:读取的大小 ,参数三:从哪里读。

返回值:成功返回s,失败返回NULL。

示例代码:

cpp 复制代码
 int main()
 {
     FILE* fp = fopen("log.txt","r");
     if(fp==NULL)
     {
          perror("fopen");
     }
     char buffer[64];
     while(1)
     {
         char* rstr = fgets(buffer,sizeof(buffer),fp);                                                                                 
         if(rstr==NULL) break;
         printf("%s\n",buffer);
     }
 
     fclose(fp);
     return 0;
 }

🌌C标准输入输出流

C 默认会打开三个输入输出流,分别是stdin(标准输入,键盘设备), stdout(标准输出,显示器设备), stderr(标准错误,显示器设备)

仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,文件指针

这些是可以直接使用的。

示例代码:

cpp 复制代码
int main()
 {
     char *msg = "hello world";
     fputs(msg,stdout);    //msg字符串打印在标准输出(显示器上)
     
     return 0;
 }

⭐fscanf


简单介绍:

fscanf 与scanf 相比多了第一个参数,scanf是从标准输入获取数据,fscanf是从stream中获取数据;

代码示例:

cpp 复制代码
int main()
 {
     FILE* fp = fopen("log.txt","r");
     if(fp==NULL)
     {
         perror("fopen");
     }
     int n = 0;
     fscanf(fp,"%d",&n);
     printf("%d\n",n);
     fclose(fp);
     
     return 0;
 }      

相关推荐
YB137526 分钟前
jetpack compose 副作用 SideEffect
android·kotlin
小小、码农1 小时前
Linux进程控制:从fork到exec,手写一个简易Shell
linux·运维·服务器
不会就选b1 小时前
Linux之进程间通信(二)---模拟进程池
linux·运维·服务器
CHB2 小时前
uni-app x 蒸汽模式 性能测试基准报告 Benchmark【Android版】
android·ios·uni-app
圆奋奋3 小时前
FreeRTOS学习(三)- 任务调度模块
学习·开源·freertos
带娃的IT创业者3 小时前
拆掉那堵墙:LibrePods 如何让 AirPods 在 Android 上重获新生
android·开源项目·airpods·librepods·生态解锁
沫璃染墨3 小时前
《从零入门Linux系统篇(十五):系统工具篇·六——GDB调试器详解:从程序执行控制到高级调试技巧》
linux·运维·服务器·c语言·c++
吃着火锅x唱着歌4 小时前
Effective C++ 学习笔记 条款40 明智而审慎地使用多重继承
c++·笔记·学习
AIgorithmGEEK4 小时前
Linux 环境变量完全指南:从入门到理解底层原理
linux·运维·服务器
xian_wwq4 小时前
【学习笔记】Prompt Engineering 没死,只是它不再够用了-2/16
笔记·学习·prompt