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!



相关文章
|
17天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
58 3
|
17天前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
48 2
|
26天前
|
Linux 应用服务中间件 Shell
linux系统服务二!
本文详细介绍了Linux系统的启动流程,包括CentOS 7的具体启动步骤,从BIOS自检到加载内核、启动systemd程序等。同时,文章还对比了CentOS 6和CentOS 7的启动流程,分析了启动过程中的耗时情况。接着,文章讲解了Linux的运行级别及其管理命令,systemd的基本概念、优势及常用命令,并提供了自定义systemd启动文件的示例。最后,文章介绍了单用户模式和救援模式的使用方法,包括如何找回忘记的密码和修复启动故障。
43 5
linux系统服务二!
|
11天前
|
Ubuntu Linux 网络安全
linux系统ubuntu中在命令行中打开图形界面的文件夹
在Ubuntu系统中,通过命令行打开图形界面的文件夹是一个高效且实用的操作。无论是使用Nautilus、Dolphin还是Thunar,都可以根据具体桌面环境选择合适的文件管理器。通过上述命令和方法,可以简化日常工作,提高效率。同时,解决权限问题和图形界面问题也能确保操作的顺利进行。掌握这些技巧,可以使Linux操作更加便捷和灵活。
15 3
|
17天前
|
安全 网络协议 Linux
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。通过掌握 ping 命令,读者可以轻松测试网络连通性、诊断网络问题并提升网络管理能力。
53 3
|
20天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
37 6
|
20天前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
55 6
|
21天前
|
机器学习/深度学习 自然语言处理 Linux
Linux 中的机器学习:Whisper——自动语音识别系统
本文介绍了先进的自动语音识别系统 Whisper 在 Linux 环境中的应用。Whisper 基于深度学习和神经网络技术,支持多语言识别,具有高准确性和实时处理能力。文章详细讲解了在 Linux 中安装、配置和使用 Whisper 的步骤,以及其在语音助手、语音识别软件等领域的应用场景。
52 5
|
21天前
|
缓存 运维 监控
【运维必备知识】Linux系统平均负载与top、uptime命令详解
系统平均负载是衡量Linux服务器性能的关键指标之一。通过使用 `top`和 `uptime`命令,可以实时监控系统的负载情况,帮助运维人员及时发现并解决潜在问题。理解这些工具的输出和意义是确保系统稳定运行的基础。希望本文对Linux系统平均负载及相关命令的详细解析能帮助您更好地进行系统运维和性能优化。
43 3
|
21天前
|
监控 网络协议 算法
Linux内核优化:提升系统性能与稳定性的策略####
本文深入探讨了Linux操作系统内核的优化策略,旨在通过一系列技术手段和最佳实践,显著提升系统的性能、响应速度及稳定性。文章首先概述了Linux内核的核心组件及其在系统中的作用,随后详细阐述了内存管理、进程调度、文件系统优化、网络栈调整及并发控制等关键领域的优化方法。通过实际案例分析,展示了这些优化措施如何有效减少延迟、提高吞吐量,并增强系统的整体健壮性。最终,文章强调了持续监控、定期更新及合理配置对于维持Linux系统长期高效运行的重要性。 ####