【linux】基础IO |文件操作符

简介: 【linux】基础IO |文件操作符

需要掌握:操作文件,本质:进程操作文件。进程和文件的关系

向文件中写入,本质上向硬件中写入->用户·没有权利直接写入->操作系统是硬件的管理者,我们可以通过操作系统往硬件写入->操作系统必须提供系统调用(默认操作系统不相信任何人)

我们使用的fopen/fwrite/fread/fprintf/scanf/printf/cin/cout/实际上都是对系统调用的接口的封装.

系统调用函数open

头文件

#include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>

open函数

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

第一个open函数的第一个参数是文件名,第二个参数是打开方式,

其中我们要了解的打开方式有

O_WRONLY//只读方式
 O_CREAT//没有该文件就创建
 O_APPEND//追加
 O_TRUNC//覆盖式写入

因为要用到close函数关闭文件,

close函数

头文件

#include <unistd.h>
int close(int fd);

有一个疑问,为什么他的 参数是int类型的,因为对应的打开方式可以是int 32中任何一位为1并且和其他区分开来,然后需要多个功能的话,按位或就可以,这是操作系统调用接口的常见方法

1.只写和没有该文件就创建

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

我们发现当前目录下没有我们要的“log.txt”

当我们运行这个程序后,发现出现了该文件

为了测试追加功能,我们通过vim往log.txt里面写入点东西

修改打开方式为只写和追加,所以修改参数2为

O_WRONLY|O_APPEND

但是我们发现log.txt这个文件的权限怎么不对呀,这里是因为如过用第一个open函数的话,就必须是已经创建好的文件,就已经有了权限,要不然就只能用第二个open函数,第二个open函数的第三个参数就是要设置的掩码值,所以我们使用第二个open函数

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

但是这里的权限是664呢,因为我们可以通过unmask来查看对应的默认掩码

我们可以将默认掩码在函数内设置为0

这段代码修改了掩码为0,并且修改其文件名


此时我们就可以修改我们的loog.txt文本文件了

使用打开方式

O_WRONLY|O_APPEND

此时我们就用到了write函数,

头文件

#include <unistd.h>

函数

ssize_t write(int fd, const void *buf, size_t count);

函数第一个参数是文件描述符,对应你打开的文件,待会在讲这个fd,文件描述符,

第二个参数是你要写入的字符串,第三个参数是要写入字符串的大小

1 #include<stdio.h>      
  2 #include <sys/types.h>  
  3 #include <sys/stat.h>  
  4 #include <fcntl.h>     
  5 #include <unistd.h>    
  6 int main()             
  7 {                      
  8   umask(0);            
  9                        
 10  int fd=open("looog.txt", O_WRONLY|O_APPEND,0666);  
 11                        
 12 if(fd<0)               
 13 {perror("open");       
 14  return 1;}            
 15  char buf[]="hello world";                                                                                         
 16 write(fd, buf,sizeof(buf));                             
 17 close(fd);                                                                                                   
 18 return 0;                                                                                                    
 19                                                                                                              
 20 }   


覆盖式写入

第二个参数修改为:

O_WRONLY| O_TRUNC
1 #include<stdio.h>
  2 #include <sys/types.h>
  3 #include <sys/stat.h>
  4 #include <fcntl.h>
  5 #include <unistd.h>
  6 int main()
  7 {
  8   umask(0);
  9 
 10  int fd=open("looog.txt", O_WRONLY| O_TRUNC,0666);                                                                 
 11                                                                                   
 12 if(fd<0)                                                                          
 13 {perror("open");                                                                  
 14  return 1;}                                                                       
 15  char buf[]="hello world";                                                        
 16    write(fd, buf,sizeof(buf));                                                    
 17 close(fd);                                                                        
 18 return 0;                                                                         
 19                                                                                   
 20 } 


除了上面的方法给文件写入数据,我们还可以通过echo写入数据

我们发现是覆盖式写入


我们发现是追加式写入


文件操作符

我们刚才使用了open函数,和write函数,里面open函数返回的是一个fd,write的第一个参数是fd,这就是我们要提到的文件操作符

为了讲清文件操作符这个概念

我们可以先来说说操作系统是如何进行文件的写入和读呢?

在我们启动进程时,默认操作系统已经帮我们打开

标准输入流:0(对应的文件标识符)—键盘

标准输出流:1(对应的文件标识符)—显示器

标准错误流:2(对应的文件标识符)—显示器

我们可以把这些外设也当成文件(linux一切皆文件)

如果是文件,当我们使用的时候,也会给他创建pcb结构来管理外设

在操作系统内,系统在访问文件的时候,只认文件描述符fd

open函数在干什么呢??

1.创建file对应的pcb管理文件属性

2.开辟文件缓冲区的空间,将文件数据加载到文件缓冲区去(延后)

3.查进程文件的文件描述表

4.将对应文件的地址填入到指针数组中去

5.返回下标

文件操作符的本质是什么呢?
内核的进程:文件映射关系的数组下标

c语言如何通过FILE*访问文件呢?

1 #include<stdio.h>
  2 int main()
  3 {
  4 FILE* fp=fopen("hot.txt","w");
  5 if(NULL==fp)
  6 {
  7 perror("fopen error");
  8 return 1;
  9 
 10 
 11 
 12 }
 13 fprintf(fp,"hello world");
 14 fclose(fp);
 15 return 0;                                                                                                          
 16 }

实际上FILE是一个c语言的一个结构体类型,里面封装了文件标识符fd

gcc -E file.c -o file.i//预处理完就停下,头文件展开

在stdio.h头文件里面

1 #include<stdio.h>
  2 int main()
  3 {
  4 printf("输入流:%d\n",stdin->_fileno);//对应结构体里面封装了文件的文件标识符
  5 printf("输出流:%d\n",stdout->_fileno);
  6 printf("错误流:%d\n",stderr->_fileno);                                                                             
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 }

接着打开的文件的文件标识符就从3开始往后


终端也是文件

我们复制ssh的渠道,左边为另一个终端

1 #include<stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 #include <sys/types.h>
  5 #include <sys/stat.h>
  6 #include <fcntl.h>
  7 
  8 int main()
  9 {
 10 while(1)
 11 {
 12 printf("pid:%d\n",getpid());
 13 
 14 
 15 
 16 
 17 
 18 }                                                     
 19 //int fd=open("/dev/pts/0",O_WRONLY| O_TRUNC,0666);
 20 //if(fd<0)                                         
 21 //  {perror("error");}                             
 22 //char arr[]="hello wokao";                        
 23 //write(fd,arr,sizeof(arr));                       
 24 //close(fd);                                       
 25                                                    
 26 }

/proc/目录下存在着正在运行的进程的pid

1 #include<stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 #include <sys/types.h>
  5 #include <sys/stat.h>
  6 #include <fcntl.h>
  7 
  8 int main()
  9 {int fd=open("/dev/pts/0",O_WRONLY| O_TRUNC,0666);
 10 if(fd<0)
 11   {perror("error");}
 12 char arr[]="hello wokao";
 13 write(fd,arr,sizeof(arr));
 14 close(fd);
 15 
 16 } 

把终端当文件写入


c语言为什么支持跨平台性

支持系统调用,也可以使用语言提供文件方法系统不同,可能导致系统调用的接口可能不一样,导致代码不具有跨平台性,所以所有的语言都想具有跨平台性,所以所有的语言要对平台的系统调用进行封装,不同语言封装,文件接口就有差别了


目录
相关文章
|
24天前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
118 2
|
4月前
|
存储 数据管理 Linux
区分Linux中.tar文件与.tar.gz文件的不同。
总之,".tar"文件提供了一种方便的文件整理方式,其归档但不压缩的特点适用于快速打包和解压,而".tar.gz"文件通过额外的压缩步骤,尽管处理时间更长,但可以减小文件尺寸,更适合于需要节约存储空间或进行文件传输的场景。用户在选择时应根据具体需求,考虑两种格式各自的优劣。
593 13
|
5月前
|
安全 Linux
Linux赋予文件000权限的恢复技巧
以上这些步骤就像是打开一扇锁住的门,步骤看似简单,但是背后却有着严格的逻辑和规则。切记,在任何时候,变更文件权限都要考虑安全性,不要无谓地放宽权限,那样可能
165 16
|
5月前
|
XML JSON Go
Go语言中的文件与IO:JSON、CSV、XML处理
本文介绍了 Go 语言中对 JSON、CSV 和 XML 三种常见数据格式的处理方法。通过标准库 `encoding/json`、`encoding/csv` 和 `encoding/xml`,可以实现结构体与数据格式之间的序列化与反序列化。JSON 适合 Web API 和前后端通信,因其清晰易读;CSV 适用于表格数据和轻量级交换;XML 则支持复杂嵌套结构,常用于配置文件和 SOAP 协议。文中提供代码示例,涵盖基本使用、嵌套结构处理及实战建议,帮助开发者高效操作这些格式。
|
6月前
|
Linux
【Linux】 Linux文件I/O常见操作技巧
以上就是Linux文件I/O操作的一些技巧,接纳它们,让它们成为你在Linux世界中的得力伙伴,工作会变得轻松许多。不过记住,技巧的运用也需要根据实际情况灵活掌握,毕竟,最适合的才是最好的。
163 28
|
5月前
|
存储 Linux 数据处理
深入剖析Linux中一切即文件的哲学和重定向的机制
在计算机的奇妙世界中,Linux的这套哲学和机制减少了不同类型资源的处理方式,简化了抽象的概念,并蕴藏着强大的灵活性。就像变戏法一样,轻轻松松地在文件、程序与设备之间转换数据流,标准输入、输出、错误流就在指尖舞动,程序的交互和数据处理因此变得既高效又富有乐趣。
92 4
|
5月前
|
Unix Go
Go语言中的文件与IO:文件读写
本文介绍了 Go 语言中文件操作的基础方法,涵盖打开与关闭文件、读取和写入文件内容、追加写入以及复制文件等功能。通过 `os`、`bufio` 和 `io` 等标准库包,提供了高效且灵活的实现方式,如使用 `os.ReadFile` 读取整个文件、`bufio.Scanner` 逐行读取、`os.Create` 创建文件以及 `io.Copy` 复制文件内容。同时强调了错误处理的重要性,例如使用 `defer` 确保文件关闭,并推荐注意文件权限设置(如 UNIX 系统中的 `0644`)。最后以表格形式总结了常用操作及其推荐方法,便于快速查阅和应用。
|
5月前
|
Go 数据处理
Go语言中的文件与IO:bufio 和 scanner
Go 标准库中的 `bufio` 包高效读写功能,适用于文件和数据处理。`bufio.Reader` 支持按行或分隔符读取,`bufio.Writer` 提供高性能写入并需调用 `Flush()` 确保数据写入。`bufio.Scanner` 是处理文本文件(如日志、配置)的利器,可按行、单词等分割内容。本文详解其用法,并给出实践建议,如统计字符数、模拟 `tail -f` 和词频分析等。
|
6月前
|
Ubuntu Linux
"unzip"命令解析:Linux下如何处理压缩文件。
总的来说,`unzip`命令是Linux系统下一款实用而方便的ZIP格式文件处理工具。本文通过简明扼要的方式,详细介绍了在各类Linux发行版上安装 `unzip`的方法,以及如何使用 `unzip`命令进行解压、查看和测试ZIP文件。希望本文章能为用户带来实际帮助,提高日常操作的效率。
775 12
|
5月前
|
Linux
linux文件重命名命令
本指南介绍Linux文件重命名方法,包括单文件操作的`mv`命令和批量处理的`rename`命令。`mv`可简单更改文件名并保留扩展名,如`mv old_file.txt new_name.txt`;`rename`支持正则表达式,适用于复杂批量操作,如`rename &#39;s/2023/2024/&#39; *.log`。提供实用技巧如大小写转换、数字序列处理等,并提醒覆盖风险与版本差异,建议使用`-n`参数预览效果。