【Linux】从零认识文件操作

这篇具有很好参考价值的文章主要介绍了【Linux】从零认识文件操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【Linux】从零认识文件操作,一起学Linux吧!,linux,服务器,java,算法,学习,c语言,c++
送给大家一句话:

要相信,所有的不美好都是为了迎接美好,所有的困难都会为努力让道。
—— 简蔓《巧克力色微凉青春》

1 前言

在C语言已经掌握文件操作的一些接口,接下来我们来从操作系统的层面来理解文件操作!!!
基础IO的篇章我们将讲解以下内容:

  1. 复习C文件IO相关操作
  2. 认识文件相关系统调用接口
  3. 认识文件描述符,理解重定向
  4. 对比fd和FILE,理解系统调用和库函数的关系
  5. 理解文件系统中inode的概念
  6. 认识软硬链接,对比区别
  7. 认识动态静态库,学会结合gcc选项,制作动静态库

2 知识回顾

C语言中要进行文件操作,就一定要先打开这个文件:fopen(),并用一个文件指针来接收
例如:FILE* fp = fopen("log.txt","w")
打开也有可能会失败,所以还要检查fp是否为空指针。当我们使用完文件之后一定一定要关闭文件:fclose(fp)

我们要进行文件操作,前提是我们的程序跑起来了!文件打开和关闭,是CPU在执行我们的程序。所以可以推断出来:

  • 打开文件的本质是进程打开文件!!!
  • 文件没有被打开的时候,文件在哪里??? 当然是磁盘了
  • 进程可以打开多个文件!!! (系统中同样可以存在多个进程) 很多的情况下,OS内部存在大量被打开的文件!那操作系统就要对打开的文件进行管理!! (那么每个打开的文件在OS内部都存在一个对应描述文件属性的结构体,类似PCB
  • 文件 = 属性 + 内容
  • 注意文件写入方式:
r   Open text file for reading.
	The stream is positioned at the beginning of the file.
	
r+  Open for reading and writing.
    The stream is positioned at the beginning of the file.
    
w   Truncate(缩短) file to zero length or create text file for writing.
    The stream is positioned at the beginning of the file.
    
w+  Open for reading and writing.
	The file is created if it does not exist, otherwise it is truncated.
	The stream is positioned at the beginning of the file.
	
a   Open for appending (writing at end of file).
    The file is created if it does not exist.
    The stream is positioned at the end of the file.
    
a+  Open for reading and appending (writing at end of file).
    The file is created if it does not exist. The initial file position
    for reading is at the beginning of the file,
    but output is always appended to the end of the file.

3 理解文件

3.1 进程和文件的关系

3.2 文件的系统调用

open

各个语言的文件接口基本都是不一样的,那么语言之间有没有共性呢???
我们来看一个系统调用:open(),我们先认识使用一下:

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

第一个参数和C语言fopen的第一个参数一致(表示文件路径或当前目录下的文件名)
第二个参数表示想怎样打开文件,传入的是标志位
第三个参数表示创建文件的权限
会返回一个数字表示是否打开成功。

  1 #include<sys/types.h>  
  2 #include<sys/stat.h>  
  3 #include<stdio.h>  
  4 #include<fcntl.h>  
  5   
  6 int main()  
  7 {  // 以只读形式打开 , 文件不存在就创建
  8   int fd = open("log.txt",O_WRONLY|O_CREAT);  
  9   if(fd < 0)  
 10   {  
 11     perror("open");  
 12     return 1;  
 13   }                                                                                                                                                                           
 14 }   

运行代码:
【Linux】从零认识文件操作,一起学Linux吧!,linux,服务器,java,算法,学习,c语言,c++
可以看的我们成功创建了一个新文件,但是文件的权限好像不对(这里因为我们没有设置对应权限,所以是乱码!)
所以才有了第三个参数,来帮助我们确定权限
int fd = open("log.txt",O_WRONLY|O_CREAT,0666); 我们在来看看
【Linux】从零认识文件操作,一起学Linux吧!,linux,服务器,java,算法,学习,c语言,c++
哎呦???怎么权限还是不对,我们设置的是666应该是rw-rw-rw-啊???这是因为创建的文件会收到文件掩码的影响:
【Linux】从零认识文件操作,一起学Linux吧!,linux,服务器,java,算法,学习,c语言,c++
所以会出现这样的情况,那怎么解决呢?

我们可以使用umask()系统调用,动态修改掩码值(只在该进程中起作用),来达到我们预期的结果:

  1 #include<sys/types.h>
  2 #include<sys/stat.h>
  3 #include<stdio.h>
  4 #include<fcntl.h>
  5 
  6 int main()
  7 {
  8   umask(0);                                                                                                                                                                   
  9   int fd = open("log.txt",O_WRONLY|O_CREAT,0666);                                                             
 10   if(fd < 0)                                                                                                  
 11   {                                                                                                           
 12     perror("open");                                                                                           
 13     return 1;                                                                                                 
 14   }                                                                                                           
 15 } 

这样就创建出来我们预期的效果了!!!

我们再来看看 flag 标志位,它是一个32位的整数,每个比特位代表一个对应功能(OS常用的系统调用接口的常用方法),也就是位图!!!每个宏定义都是一个对应比特位设置为1,想要实现多个功能就进行 | 按位与操作就可以了!!!

常用的标志位参数:
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_RDWR : 读,写打开
上面三个常量,必须指定一个且只能指定一个

O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
O_APPEND: 追加写

write

接下来我们写入来试试。

  1 #include<sys/types.h>
  2 #include<sys/stat.h>
  3 #include<stdio.h>
  4 #include<fcntl.h>
  5 
  6 int main()
  7 {
  8   umask(0);
  9   int fd = open("log.txt",O_WRONLY|O_CREAT,0666);
 10   if(fd < 0)
 11   {
 12     perror("open");
 13     return 1;
 14   }
 15 
 16   const char* message = "hello linux file!\n";
 17   write(fd , message,strlen(message));
 18 
 19   close(fd);
 20   return 0;                                                                                                                                                                   
 21 }    

这样就成功写入进去了(注意没有写入\0哦)
【Linux】从零认识文件操作,一起学Linux吧!,linux,服务器,java,算法,学习,c语言,c++
但是我们在写入aaaa时会发现,原本文件并没有清空,也就是open默认不会清空文件!!!,这时我们加入新的标记位O_TRUNC,就能打开文件就清空了!现在就不会出现叠加的情况了!通过不同的标识位可以做到不同功能(比如追加写入)

文件 fd 值

接下来我们来认识一下文件fd:

#include<sys/types.h>  
  2 #include<sys/stat.h>  
  3 #include<stdio.h>  
  4 #include<fcntl.h>  
  5 #include<string.h>  
  6   
  7 int main()  
  8 {  
  9   int fda = open("loga.txt",O_WRONLY|O_CREAT|O_TRUNC);  
 10   printf("fda: %d\n",fda);  
 11   
 12   int fdb = open("logb.txt",O_WRONLY|O_CREAT|O_TRUNC);  
 13   printf("fda: %d\n",fdb);  
 14     
 15   int fdc = open("logc.txt",O_WRONLY|O_CREAT|O_TRUNC);  
 16   printf("fda: %d\n",fdc) ;   
 17   return 0
 18 }  

来看效果:
【Linux】从零认识文件操作,一起学Linux吧!,linux,服务器,java,算法,学习,c语言,c++
每个文件都有对应的不同的fd值(类似进程的 pid),为什么是从3开始的呢,因为0 1 2 ,都是已经设置好的文件:

  • 0 : 标准输入 – 键盘
  • 1 : 标准输出 – 显示器
  • 2 : 标准错误 – 显示器

在语言层(比如C语言),也会默认打开这三个(stdin stdout stderr)。我们使用文件对应的fd值,也可以实现写入操作了。
那么在操作系统内部,是如何实现的呢?
文件的管理类似进程管理,会有对应的struct filel来进行管理,而且多个进程可能打开同一个文件,所以进程里也一定有管理该进程打开的文件的结构体(struct files_struct),里面包含一个指针数组,每个指针都指向对应的文件,数组的下标也就是每个文件的fd值,所以上层的系统调用使用fd值(数组下标)就能访问对应文件!!!
【Linux】从零认识文件操作,一起学Linux吧!,linux,服务器,java,算法,学习,c语言,c++
这时也就可以总结一下open系统调用做了哪些事情:

  1. 创建file
  2. 开辟文件缓冲区的空间,加载文件数据
  3. 查进程的文件描述符表(struct files_struct *file)
  4. file 地址,填入对应表的下表中
  5. 返回下标(fd)

3.3 语言层如何理解

C语言中FILE其实是一个结构体类型,内部一定会封装文件fd!!!来看

#include<sys/types.h>  
  2 #include<sys/stat.h>  
  3 #include<stdio.h>  
  4 #include<fcntl.h>  
  5 #include<string.h>  
  6   
  7 int main()  
  8 {  
  9   
 10   printf("stdin->fd: %d\n",stdin->_fileno);  
 11   printf("stdin->fd: %d\n",stdout->_fileno);  
 12   printf("stdin->fd: %d\n",stderr->_fileno);  
 13   
 14   FILE* fp = fopen("log.txt","w");  
 15   if(fp == NULL) return 1;  
 16   printf("fd : %d\n",fp->_fileno);  
 17   
 18   FILE* fp1 = fopen("log1.txt","w");  
 19   if(fp1 == NULL) return 1;  
 20   printf("fd : %d\n",fp1->_fileno);  
 21   
 22   FILE* fp2 = fopen("log2.txt","w");  
 23   if(fp2 == NULL) return 1;  
 24   printf("fd : %d\n",fp2->_fileno);    
 25   return 0
 26 }

来看运行效果:
【Linux】从零认识文件操作,一起学Linux吧!,linux,服务器,java,算法,学习,c语言,c++
怎么样,我们的猜测没有问题!!!所以语言层的文件操作函数,本质底层是对系统调用的封装!通过不同标志位的封装来体现w r a+等不同打开类型!
我们在使用文件操作时,一般都要使用语言层的系统调用,来保证代码的可移植性。因为不同系统的系统调用可以会不一样!

下一篇文章我们来看文件操作的应用!!!文章来源地址https://www.toymoban.com/news/detail-846584.html

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

到了这里,关于【Linux】从零认识文件操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux操作系统配置代理服务器

    PS:本文只是针对Linux操作系统对于代理服务器的配置操作,不涉及广告        代理服务器英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息。形象的说:它是网络信息的中转站。在一般情况下,我们使用网络浏览器直接去连接其他Internet站点取得网络信息时,须

    2024年02月13日
    浏览(67)
  • 从零学习Linux操作系统 第二十二部分 企业域名解析服务的部署及安全优化

    关于dns的名词解释:dns: domain name service(域名解析服务) 关于客户端: /etc/resolv.conf dns指向文件 A记录 ##ip地址叫做域名的Address 记录 SOA ##授权起始主机 关于服务端 bind 安装包 named 服务名称 /etc/named.conf 主配置文件 /var/named 数据目录 端口 53 关于报错信息: 1.no servers could be reach

    2024年02月22日
    浏览(46)
  • Linux 操作系统安装 Apache 服务器

    摘要 电子计算机诞生以来,计算机操作系统的研究有了很大的发展。我们 身边最熟悉的操作系统有微软的 windows。当然这只是相对于 pc 端来说。现在 操作系统进入了社会生活的各个方面,涉及大型计算机、个人计算机、移动便携 设备、其他自动化设备等各个层次的应用领域

    2024年02月04日
    浏览(66)
  • linux服务器间文件传输

            当对服务器应用或文件进行迁移时,一般的方法是找一台电脑,先把文件从A服务器下载到电脑,然后再从电脑上传到B服务器。但这样传有几个问题:         1、步骤繁琐,必须通过电脑作为中介         2、需要安装额外的软件,比如winscp、FileZilla 等传输工具  

    2024年02月10日
    浏览(49)
  • Linux服务器移动文件命令

    mv(move) 命令可以将文件和目录从一个位置 移动 到另一个位置;         它也可以用来 重命名 文件和目录。 mv命令语法         source 可以是一个或多个文件或目录;         destination 总是一个文件或目录;         如果我们以单个文件为源,以一个目录为目标

    2023年04月25日
    浏览(61)
  • 【Linux】FTP文件服务器

    FTP (File transfer protocol) 是TCP/IP 协议组中的协议之一。他最主要的功能是在服务器与客户端之间进行文件的传输。FTP就是实现两台计算机之间的拷贝,从远程计算机拷贝文件至自己的计算机上,称之为“下载 (download)”文件。将文件从自己计算机中拷贝至远程计算机上,则称

    2024年02月10日
    浏览(60)
  • linux服务器文件实时同步

    在做系统集群部署时,涉及到两个或多个服务器之间文件同步.在软件层面linux服务环境找到以下两种同步方式 利用linux NFS功能将网络共享文件挂载成本地目录 采用文件监听,实时推送 服务器资源如下 服务器1 10.2.4.51 ,作为主服务器 服务器2 10.2.4.52 ,作为从服务器 2.1 主服务器

    2024年03月09日
    浏览(70)
  • Java中将本服务器的文件拷贝到另一个服务器(Linux to Linux)

    在Java中,将文件从一个服务器复制到另一个服务器,你可以使用Secure Copy(SCP)进行操作。Java中的 JSch 库可以进行此操作。 首先,需要添加 JSch 库依赖到你的项目中。如果你使用的是Maven,可以添加以下依赖: 以下是一个使用 JSch 进行SCP操作的示例: 这段代码首先创建了一

    2024年02月13日
    浏览(64)
  • 【运维】Linux 跨服务器复制文件文件夹

    如果是云服务 建议用内网ip scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的。可能会稍微影响一下速度。当你服务器硬盘变为只读 read only system时,用scp可以帮你把文件移出来

    2024年02月08日
    浏览(74)
  • 【Linux】搭建SFTP文件服务器

    1.11 特点 FTP(File Transfer Protocol)是一种用于在计算机之间传输文件的标准网络协议。它提供了一种简单而常用的方式来上传和下载文件,以及进行文件管理操作。 FTP协议的主要特点包括: 客户端-服务器架构 :FTP使用客户端-服务器模型,其中客户端是发送文件请求的一方,

    2024年02月07日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包