Linux系统IO—探索输入输出操作的奥秘

简介: Linux系统IO—探索输入输出操作的奥秘

什么是Linux系统IO?

       Linux系统IO,指的是在Linux操作系统中进行的所有输入输出操作。这些操作可以通过不同的方式实现,包括系统I/O和标准I/O。

       具体来说,系统I/O是Linux系统内核提供的API,主要用于处理底层的输入输出任务。例如,传统的访问方式是通过write()和read()两个系统调用实现的,通过read()函数读取文件到缓存区中,然后通过write()方法把缓存中的数据输出到网络端口。

       另一方面,标准I/O是C语言在Linux操作系统下的API,主要用于处理应用程序的输入输出任务。它提供了一套丰富的库函数和系统调用,方便开发者进行文件读写操作。


       以下是一些常用的系统IO:

  1. 打开文件:open()、creat()
  2. 关闭文件:close()
  3. 读取文件:read()
  4. 写入文件:write()
  5. 移动文件指针:lseek()
  6. 删除文件或目录:unlink()、rmdir()
  7. 创建目录:mkdir()
  8. 删除目录:rmdir()、rm()
  9. 重命名文件或目录:rename()
  10. 获取文件状态:stat()、fstat()
  11. 更改文件权限和时间戳:chmod()、chown()、utime()

      本文主要介绍最常用的open()、close()、read()、write()、lseek()。


open()

       Linux中的open()函数用于打开或创建一个文件,并返回一个文件描述符。它的定义如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

    参数说明:

  1. pathname:要打开或创建的文件的路径名。
  2. flags:表示文件打开方式和访问权限的标志位,如O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(读写)等。需要注意的是:flags是可以选择多种权限的,比如:O_RDWR | O_CREAT | O_APPEND(以读写的方式打开,以追加的方式打开文件,并且如果该文件不存在则创建该文件)。
  3. mode:当指定了O_CREAT标志时,表示需要使用文件的权限模式,如S_IRUSR(用户读)、S_IWUSR(用户写)等。比如上面我们设置了O_CREAT,那么在就必须设置mode,此时我们要设置对应的权限:比如:0666(设置为所有人可读写),但是需要注意的是默认 umask=0002,因此我们需要在文件open()前设置umask(0)。一个例子:

       🌰  

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
  umask(0);
    int fd = open(FILE_NAME, O_WRONLY | O_CREAT | O_APPEND, 0666);
    close(fd);
    return 0;
}

返回值:

       成功时,返回一个非负整数,表示文件描述符;失败时,返回-1,并设置errno。

       详细的操作:

close()

       在Linux系统中,close()函数的主要功能是关闭一个已打开的文件描述符,以释放相应的系统资源。具体来说,close()函数会释放与该进程关联并由该进程拥有的文件上保留的所有记录锁,并使文件描述符不再引用任何文件,从而允许系统重用该文件描述符。


       详细的操作:

write()

       在Linux系统中,write()函数用于向文件中写入数据。其函数原型为:

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

       其中,参数fd是文件描述符,表示要写入的文件;buf是一个指向要写入数据的缓冲区的指针;count是要写入的字节数。

       当调用成功时,write()函数返回实际写入的字节数。如果返回的值与count相等,说明所有数据均已成功写入文件。如果返回的值小于count,则说明发生了错误或某些数据未能写入。

       当发生错误时,write()函数会设置全局变量errno来指示具体的错误类型。例如:


  • EACCES:访问被拒绝(通常是由于权限不足)。
  • EPIPE:向一个已经关闭的管道或套接字发送数据。
  • EAGAIN或EWOULDBLOCK:文件已被其他进程锁定或者当前没有可用的数据空间。
  • EBADF:文件描述符无效。
  • EINTR:系统中断,比如信号等导致了write()函数被提前终止。
  • EIO:输入/输出错误,通常由硬件问题引起。
  • ENOSPC:磁盘已满或者设备上没有足够的空间来存储数据。


需要注意的是,write()函数并不会将数据立即写入磁盘,而是将其缓存在内核中,等到满足一定的条件后才会真正写入磁盘。因此,如果想要确保数据被立即写入磁盘,可以使用fsync()函数或fdatasync()函数对文件进行同步操作。

       🌰

   #include<stdio.h>
   #include<sys/types.h>
   #include<unistd.h>
   #include<sys/stat.h>                                    
   #include<fcntl.h>                    
   #include<string.h>
   #define FILE_NAME "1.txt"                                  
   int main()                           
   {                    
    umask(0);                             
    int fd = open(FILE_NAME, O_WRONLY | O_CREAT | O_APPEND, 0666);
    char buf[1024]={0};
    fgets(buf,sizeof(buf),stdin);                                    
    int wd=write(fd,&buf,strlen(buf)-1);//strlen(buf)-1是为了去掉\n直接在后面接                                           
    printf("成功写入%d个数据\n",wd);                          
    close(fd);                          
    return 0;                                         
  }      

详细的操作:

read()

       在Linux中,read()函数用于从文件描述符中读取数据。它通常与open()函数一起使用,以打开一个文件并获取文件描述符。

       read()函数的原型如下:


#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

       其中,fd是文件描述符,buf是一个指向缓冲区的指针,count是要读取的字节数。

      read()函数返回实际读取的字节数,如果返回值小于请求的字节数,则表示已到达文件末尾或发生了错误如果返回值为-1,则表示发生了错误。

🌰

   #include<stdio.h>
   #include<sys/types.h>
   #include<unistd.h>
   #include<sys/stat.h>                                    
   #include<fcntl.h>                    
   #include<string.h>
   #define FILE_NAME "1.txt"  
  int main()
    {
      int fd=open(FILE_NAME,O_RDONLY);
      char buf[1024]={0};
      int rd=read(fd,buf,sizeof(buf));
      printf("读取:%d数据\n",rd);
      printf("%s\n",buf);                                                          
      close(fd);
      return 0;
    }

      详细的操作:

lseek()

       在Linux操作系统中,lseek()函数是一个关键的工具,用于改变文件的当前读写位置。这个函数主要应用在对文件进行随机访问的时候。

       其函数原型为:

1.#include <sys/types.h>
#include <unistd.h>
off_t lseek (int fd, off_t offset, int whence);


   其中,参数fd表示需要进行操作的文件描述符;offset表示偏移量,这是要移动的字节数,可正可负;whence则代表偏移起始位置,有以下三种选择:

  • SEEK_SET: 从文件头部开始偏移offset个字节。
  • SEEK_CUR: 从文件当前读写的指针位置开始,增加offset个字节的偏移量。
  • SEEK_END: 文件偏移量设置为文件的大小加上偏移量字节。

     

值得注意的是,lseek()函数成功执行后会返回新的文件偏移量,如果操作失败则返回-1。通过这个函数,我们可以实现对文件的任意位置的读写操作,而不再局限于顺序读取或者写入数据。这对于管理大文件尤其有用,因为它允许我们直接跳转到所需的特定部分,而不是从头到尾按顺序处理文件内容。


🌰

  #include<stdio.h>
   #include<sys/types.h>
   #include<unistd.h>
   #include<sys/stat.h>                                    
   #include<fcntl.h>                    
   #include<string.h>
   #define FILE_NAME "1.txt"  
  int main()
    {
      int fd=open(FILE_NAME,O_RDONLY);
      char buf[1024]={0};
      for(int i=0;i<3;i++)//打印三次文件
      {
        lseek(fd,0,SEEK_SET);//注意前下图中前部分注释掉该段,后半没注释    
        int rd=read(fd,buf,sizeof(buf));
        printf("读取:%d数据\n",rd);
        printf("%s\n",buf); 
        *buf='\0';//清空缓冲区操作
      }
      close(fd);
      return 0;
    }

详细的操作:


                       感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o!



相关文章
|
5天前
|
运维 Ubuntu Linux
Linux系统之ncdu命令的基本使用
【8月更文挑战第8天】Linux系统之ncdu命令的基本使用
13 2
Linux系统之ncdu命令的基本使用
|
1天前
|
Linux Shell
Linux系统
是对Linux系统进行管理的命令。对于Linux系统来说,无论是中央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命令类似。linux命令在系统中有两种类型:内置Shell命令和Linux命令。
|
7天前
|
存储 安全 Unix
揭秘Linux配置之谜:为何重启成常态?动态刷新配置竟成奢望?一场关于系统稳定性与灵活性的较量!
【8月更文挑战第12天】Linux以其卓越性能在各领域广泛应用,但配置更新需重启而非动态刷新。这源于系统架构的静态设计、配置管理机制的局限、安全考量及性能优化需求。配置文件存储于磁盘,改动不自动反映至内存;服务管理依赖systemd等初始化系统,启动时加载配置而不主动监测变更;动态刷新可能引入安全风险;频繁更新配置亦影响性能。开发者可通过信号或IPC机制实现在特定信号下重新加载配置。
21 4
|
4天前
|
存储 NoSQL Java
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
该博客文章展示了如何在Linux虚拟机上使用Redis和Jedis客户端实现手机验证码的验证功能,包括验证码的生成、存储、验证以及限制每天发送次数的逻辑,并提供了测试结果截图。
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
|
4天前
|
Linux
虚拟机安装Linux系统的网络配置
该博客文章提供了解决虚拟机中Linux系统网络问题的多种方法,包括重置网络服务、修改网络配置文件、使用不同网络模式等,以确保虚拟机能够成功连接到网络。
虚拟机安装Linux系统的网络配置
|
5天前
|
监控 Linux Shell
"揭秘!一键掌控Linux服务器健康的秘密武器——超实用系统检查脚本,让你的服务器稳如老狗,告别宕机烦恼!"
【8月更文挑战第14天】服务器宕机或资源耗尽会严重影响业务。为此,你需要一个Linux系统检查脚本来守护服务器健康。它可以自动检测潜在问题如磁盘满载、内存泄漏等,避免服务中断。脚本应包括磁盘空间、内存/CPU使用、系统时间准确性、关键服务状态及系统日志分析等检查项。通过编写并定期运行这样的脚本,可以显著提高服务器的稳定性和可靠性。
16 1
|
2天前
|
网络协议 Ubuntu Linux
会Linux系统上配IPv6地址的网工,那真是老6了!
会Linux系统上配IPv6地址的网工,那真是老6了!
|
4天前
|
开发框架 Unix Linux
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
15 0
|
7天前
|
Linux Python
Linux——删除系统python导致yum无法使用
Linux——删除系统python导致yum无法使用
20 0
|
7天前
|
Linux
Linux——查看系统版本信息
Linux——查看系统版本信息
19 0