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!



相关文章
|
4天前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
28 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
27天前
|
缓存 Java Linux
如何解决 Linux 系统中内存使用量耗尽的问题?
如何解决 Linux 系统中内存使用量耗尽的问题?
115 48
|
16小时前
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
78 62
|
1天前
|
Ubuntu Linux C++
Win10系统上直接使用linux子系统教程(仅需五步!超简单,快速上手)
本文介绍了如何在Windows 10上安装并使用Linux子系统。首先,通过应用商店安装Windows Terminal和Linux系统(如Ubuntu)。接着,在控制面板中启用“适用于Linux的Windows子系统”并重启电脑。最后,在Windows Terminal中选择安装的Linux系统即可开始使用。文中还提供了注意事项和进一步配置的链接。
10 0
|
24天前
|
Ubuntu Linux 网络安全
linux系统ubuntu中在命令行中打开图形界面的文件夹
在Ubuntu系统中,通过命令行打开图形界面的文件夹是一个高效且实用的操作。无论是使用Nautilus、Dolphin还是Thunar,都可以根据具体桌面环境选择合适的文件管理器。通过上述命令和方法,可以简化日常工作,提高效率。同时,解决权限问题和图形界面问题也能确保操作的顺利进行。掌握这些技巧,可以使Linux操作更加便捷和灵活。
17 3
|
29天前
|
存储 运维 Linux
如何在 Linux 系统中使用 envsubst 命令替换环境变量?
`envsubst` 是 Linux 系统中用于替换文本中环境变量值的实用工具。本文分三部分介绍其工作原理、使用方法及实际应用,包括配置文件替换、脚本执行中环境变量替换和动态生成文件等场景,帮助用户高效利用 `envsubst` 进行开发和运维工作。
49 4
|
27天前
|
Linux
在 Linux 系统中,`find` 命令
在 Linux 系统中,`find` 命令
29 1
|
27天前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
56 1
|
27天前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
12天前
|
存储 Oracle 安全
服务器数据恢复—LINUX系统删除/格式化的数据恢复流程
Linux操作系统是世界上流行的操作系统之一,被广泛用于服务器、个人电脑、移动设备和嵌入式系统。Linux系统下数据被误删除或者误格式化的问题非常普遍。下面北亚企安数据恢复工程师简单聊一下基于linux的文件系统(EXT2/EXT3/EXT4/Reiserfs/Xfs) 下删除或者格式化的数据恢复流程和可行性。