> 技术文档 > 深入理解Linux底层文件操作:write、read、open、close、lseek和ioctl命令详解

深入理解Linux底层文件操作:write、read、open、close、lseek和ioctl命令详解


文章目录

  • 深入理解Linux底层文件操作:write、read、open、close、lseek和ioctl命令详解
    • 1. write 系统调用
      • 1.1 功能概述
      • 1.2 用法
      • 1.3 返回值
      • 1.4 注意事项
    • 2. read 系统调用
      • 2.1 功能概述
      • 2.2 用法
      • 2.3 返回值
      • 2.4 注意事项
    • 3. open 系统调用
      • 3.1 功能概述
      • 3.2 用法
      • 3.3 返回值
      • 3.4 打开方式
      • 3.5 权限设置
    • 4. close 系统调用
      • 4.1 功能概述
      • 4.2 用法
      • 4.3 返回值
      • 4.4 注意事项
    • 5. lseek 系统调用
      • 5.1 功能概述
      • 5.2 用法
      • 5.3 返回值
      • 5.4 注意事项
    • 6. ioctl 系统调用
      • 6.1 功能概述
      • 6.2 用法
      • 6.3 参数说明
    • 总结

深入理解Linux底层文件操作:write、read、open、close、lseek和ioctl命令详解

在Linux中,文件操作是开发中至关重要的一部分。Linux通过一系列的底层系统调用为文件操作提供支持,这些系统调用不仅涉及文件的读取和写入,还涵盖了文件位置的控制以及设备的管理。本文将详细介绍几个常见的文件操作系统调用:writereadopencloselseekioctl,并结合代码示例进行深入讲解,帮助开发者更好地理解和使用这些底层文件操作命令。

1. write 系统调用

1.1 功能概述

write 是Linux中的一个底层文件写操作系统调用,它用于将数据从缓冲区写入文件。它直接操作文件描述符,能够把数据写入到标准输出(stdout)、标准错误(stderr)或任何其他文件。

1.2 用法

#include #include #include #include int main(void) { char buffer[] = \"hello world\\n\"; int len = write(1, buffer, sizeof(buffer)); if(len < 0){ printf(\"write to stdout failed. reason: %s\\n\", strerror(errno)); } else { printf(\"write %d bytes.\\n\", len); } return 0;}

1.3 返回值

  • 成功:返回实际写入的字节数。
  • 失败:返回 -1,此时可以通过 errno 查看具体的错误信息。

1.4 注意事项

  • write 是从文件的当前指针位置开始写入数据。如果文件是刚打开的,文件指针会指向文件的头部,写入操作会从头开始。
  • 可以用于写入标准输出和标准错误输出。

2. read 系统调用

2.1 功能概述

read 是Linux中用于从文件中读取数据的系统调用。它将从指定的文件描述符中读取数据,并将数据存储到指定的缓冲区中。这个系统调用通常用于从文件、终端等设备中获取输入。

2.2 用法

#include #include #include int main(void) { char buffer[1024]; int cnt = read(0, buffer, sizeof(buffer)); // 从标准输入读取 if (cnt > 0) { write(1, buffer, cnt); // 输出到标准输出 } return 0;}

2.3 返回值

  • 大于 0:表示实际读取的字节数。
  • 等于 0:表示已到达文件尾部,表示文件读取完毕。
  • 小于 0:表示发生了错误,可以通过 errno 获取具体的错误信息。

2.4 注意事项

  • read 的第三个参数表示最多能读取的字节数,但实际读取字节数可以小于这个值。如果文件较短或者文件指针指向文件的末尾,实际读取的字节数可能会小于请求读取的字节数。

3. open 系统调用

3.1 功能概述

open 系统调用用于打开文件并返回文件描述符,这个文件描述符是后续所有文件操作的基础。它可以用来指定文件的打开模式、权限等。

3.2 用法

#include #include #include #include int main(void) { int fd = open(\"test.txt\", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if(fd < 0){ printf(\"open file failed. reason: %s\\n\", strerror(errno)); exit(-1); } close(fd); return 0;}

3.3 返回值

  • 成功:返回文件描述符,值为一个非负整数。
  • 失败:返回 -1,此时可以通过 errno 获取具体的错误信息。

3.4 打开方式

  • O_RDONLY:只读模式打开文件。
  • O_WRONLY:只写模式打开文件。
  • O_RDWR:读写模式打开文件。
  • O_CREAT:如果文件不存在,则创建文件。如果文件已存在,则打开文件。
  • O_EXCL:如果与 O_CREAT 一起使用且文件已存在,则返回错误。
  • O_APPEND:以追加模式打开文件,文件写入操作总是从文件末尾开始。
  • O_TRUNC:如果文件已经存在且成功打开,则将文件内容截断为零长度。

3.5 权限设置

open 函数的第三个参数用于设置文件权限,特别是当使用 O_CREAT 创建新文件时。常见的权限设置常量包括:

  • S_IRUSR:文件所有者可读。
  • S_IWUSR:文件所有者可写。
  • S_IXUSR:文件所有者可执行。
  • 权限通常采用八进制表示,例如 0600 表示文件所有者可读可写,其他用户没有任何权限。

4. close 系统调用

4.1 功能概述

close 用于关闭已打开的文件描述符,释放文件资源。文件描述符被关闭后,其他进程或线程无法再使用该描述符。

4.2 用法

#include #include #include int main(void) { int fd = open(\"test.txt\", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if(fd < 0) { perror(\"Failed to open file\"); return -1; } close(fd); // 关闭文件 return 0;}

4.3 返回值

  • 成功:返回 0
  • 失败:返回 -1,此时可以通过 errno 获取具体的错误信息。

4.4 注意事项

  • 关闭文件描述符后,可以重新分配文件描述符。因此,应该在文件操作结束后立即关闭文件描述符,释放资源。

5. lseek 系统调用

5.1 功能概述

lseek 系统调用用于更改文件的读写指针位置。它允许开发者在文件中随意定位指定位置,以便进行读取或写入操作。

5.2 用法

#include #include #include int main(void) { int fd = open(\"test.txt\", O_RDONLY); if(fd < 0){ perror(\"Failed to open file\"); return -1; } off_t file_size = lseek(fd, 0, SEEK_END); // 获取文件大小 printf(\"File size: %ld bytes\\n\", file_size); close(fd); return 0;}

5.3 返回值

  • 成功:返回新的文件指针位置,即当前文件头到文件指针的偏移量。
  • 失败:返回 -1,并将 errno 设置为错误码。

5.4 注意事项

  • SEEK_SET:从文件开头开始偏移。
  • SEEK_CUR:从当前指针位置开始偏移。
  • SEEK_END:从文件末尾开始偏移。

6. ioctl 系统调用

6.1 功能概述

ioctl 是一个用于控制设备的系统调用。它是Linux中设备驱动程序用于与硬件设备进行交互的接口函数。通过 ioctl,我们可以配置设备的工作参数,如串口的波特率、硬盘的传输速率等。

6.2 用法

#include #include #include #include int main(void) { int fd = open(\"/dev/ttyS0\", O_RDWR); if(fd < 0){ perror(\"Failed to open device\"); return -1; } int cmd = TIOCGWINSZ; // 获取窗口大小的命令 ioctl(fd, cmd, NULL); // 执行ioctl命令 close(fd); return 0;}

6.3 参数说明

  • fd:设备的文件描述符,通过 open 打开设备文件后得到。
  • cmd:控制命令,用于指定设备的控制操作。
  • arg:根据控制命令的不同,可能需要传递一些额外的参数。

总结

通过本文的讲解,我们详细探讨了 writereadopencloselseekioctl 这些底层文件操作系统调用。每个系统调用都具有其独特的功能和用途,掌握它们的用法对于编写高效的文件操作程序至关重要。理解这些系统调用的细节将帮助你更好地进行文件管理、设备控制以及性能优化。希望本文的内容对你理解Linux的文件操作有所帮助。