open/read/write/close等文件相关系统调用接口

本文介绍了操作系统中文件操作的基础知识,包括open、close、read和write等系统调用的使用方法及注意事项,对比了无缓冲I/O与C标准I/O库函数的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、系统调用
操作系统会对外表现为一个整体,但是会暴露自己的部分接口,这由操作系统提供的部分接口,称为系统调用。
2、库函数
系统调用进行适度封装,从而形成了库,有利于开发者进行二次开发。
下面我们就来解释系统函数与库函数的关系:
在下面这张图我们可以看到操作系统在底层软硬件的分层结构,同时观察到lib库函数所在与系统调用的关系,显然他们是上下级的关系,lib是对系统调用的二次封装,方便二次开发。
这里写图片描述
今天我们就来认识下一些文件相关的系统函数
open、close、write、read等被称为无缓冲I/O(Unbuffered I/O)函数,用户程序在读写文件时既可以调用c标准库函数,也可以直接调用底层的Unbuffered I/O函数。
然而open、close、write、read等系统的函数成为无缓冲I/O函数,那么这些函数的各自的使用场景是什么呢?

  • 用Unbuffered I/O函数每次读写都要进内核,调一个系统调用比调一个用户控件的函数要慢很多,所以在用户程序开辟I/O缓冲区还是必要的,用C标准I/O库函数比较方便。
  • 用C标准I/O库函数要时刻注意I/O缓冲区和实际文件有可能不一致,在必要时调用fflush(3)。
  • UNIX的传统是Everything is a file(一切皆文件),I/O函数不仅可以读写文件还可以读写设备。在读写设备时通常是不希望有缓冲的。比如网络设置的读写就希望是实时读写。
  • C标准库函数是C标准的一部分,而Unbuffered I/O函数是UNIX标准的一部分。只有在UNXI平台上才能用Unbuffered I/O函数,windows上不行。

1. open
这里写图片描述
注释:

1)函数说明:用来打开一个一个已经存在的文件或者用来创建一个普通文件。
2)参数解释:
pathname:文件名
flags:打开文件的方法
mode:若文件不存在,设置新文件的权限
返回值:成功则返回文件描述符,否则返回-1
对于open函数来说,第三个参数仅当创建新文件时(即使用了O_CREAT 时)才使用,用于指定文件的访问权限位。
3) 返回值:成功则返回文件描述符,否则返回-1

flags 用于指定文件的打开/创建模式,这个参数可由以下常量(定义于fcntl.h)通过逻辑位或逻辑构成。

O_RDONLY 只读模式
O_WRONLY 只写模式
O_RDWR 读写模式。
2)flags:

打开/创建文件时,至少得使用上述三个常量中的一个。
以下常量是选用的:

O_APPEND 每次写操作都写入文件的末尾 O_CREAT 如果指定文件不存在,则创建这个文件 O_EXCL
如果要创建的文件已存在,则返回-1,并且修改errno的值 O_TRUNC
如果文件存在,并且以只写/读写方式打开,则清空文件全部内容(即将其长度截短为0) O_NOCTTY
如果路径名指向终端设备,不要把这个设备用作控制终端。 O_NONBLOCK
如果路径名指向FIFO/块文件/字符文件,则把文件的打开和后继I/O

2、close
这里写图片描述
注释:
(1)函数说明:关闭指定文件
(2)函数解释:fd—–文件描述符,用来指向要操作的文件的文件结构体
(3)返回值:若成功返回0,失败返回-1;
注意:关闭一个文件时也释放该进程加在该文件上的所有记录锁,当一个进程终止时,它所有的打开文件都由内核自动关闭。
3、read函数
这里写图片描述
注释:
(1)函数说明:是从 fd所描述的打开文件中读取 buf所指缓冲区中的 n个字节。
(2)参数说明
fd:文件描述符,用来指向要操作的文件的文件结构体
buf:一块内存空间
count:请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文件的当前读写位置向后移。
ssize_t:有符号整型
(3)返回值:成功返回读取的字节数,出错返回-1并设置errno,如果在调用read之前已到达文件末尾,则这次read返回0。
注意:读操作从文件的当前位移量处开始,在成功返回之前,该位移量增加实际读的字数

#include <stdio.h>
  2 #include <unistd.h>
  3 
  4 int main(){
  5     char buf[1024];
  6     ssize_t s=read(0,buf,sizeof(buf)-1);
  7     //从屏幕上读取数据,包括换行符
  8      printf("%d\n",sizeof(buf)-1);
  9      printf("s=%d\n",s);
 10      buf[s]=0;
 11      printf("%d\n",strlen(buf));
 12      printf("%d\n",sizeof(buf));
 13      return 0;
 14 }           

这里写图片描述

read时如果fd中的数据小于要读取的数据,就会引起堵塞,可以添加换行符)(回车)就不会引起堵塞了。从终端设备读,通常以行为单位,读到换行符就返回,换行符也算读到的内容。

4、write
这里写图片描述
注释:
(1)函数说明:将buf所指向的缓冲区的n字节写入fd所描述的打开文件中
(2)参数说明:
fd文件指针
作用: 把buf中的nbyte大小的数据写入fd
返回值: 写入文档的字节数(成功);-1(出错)
write函数把buf中nbyte写入文件描述符handle所指的文档,成功时返回写的字节数,错误时返回-1.

<think>好的,用户现在想了解Linux文件操作中openwriteclose等函数的具体示例与用法。我需要根据他们提供的引用内容来组织回答,并确保符合之前提到的格式要求,比如使用中文、行内数学表达式用$...$,独立公式用$$...$$,还有生成相关问题。 首先,我得回顾用户提供的引用内容。引用[1]到[5]主要涉及openwriteclose系统调用的使用示例和基本概念。比如引用[2]提到open函数的参数和返回值,引用[3]和[4]给出了具体的代码示例,引用[5]则区分了系统调用和C库函数的不同。用户之前的问题是关于打开文件夹的,现在转向文件操作函数,可能是在深入学习Linux文件管理。 接下来,我需要整理这些信息,分步骤解释每个函数的用法,并附上示例代码。用户可能需要了解函数原型、参数意义、返回值以及常见错误处理。例如,open函数的flags参数如O_RDWR、O_CREAT等,mode参数的权限设置,write函数如何写入数据,close的作用等。同时,要注意用户可能遇到的权限问题,比如如何正确设置文件权限,或者在打开文件时处理错误。 需要确保代码示例正确,并符合用户提供的引用中的写法。比如引用[3]中的代码结构,包含头文件、错误检查、写操作后的关闭等。同时,要指出系统调用和库函数的不同,如引用[5]提到的open系统调用,而fopen是库函数,这可能在回答中需要提及,帮助用户理解两者的区别。 可能还需要考虑用户的实际应用场景,比如创建新文件、追加内容、读取数据等,给出不同的示例。例如,使用O_APPEND标志在文件末尾追加内容,或者使用lseek调整文件偏移量。同时,错误处理是关键,比如检查返回值是否为-1,并处理相应的错误情况。 在组织内容时,按照函数分点,每个函数下说明用途、参数、返回值、示例和注意事项。这样结构清晰,方便用户逐步学习。此外,用户可能对权限设置(如S_IRUSR)不太熟悉,需要解释这些宏的含义,以及如何组合使用。 最后,生成相关问题时要考虑用户可能的后续疑问,比如错误处理的最佳实践、不同打开模式的影响、系统调用与库函数的性能差异等。确保问题覆盖用户可能深入学习的方面。</think>在Linux系统中,文件操作的核心系统调用函数包括$open()$、$write()$和$close()$。以下为详细用法及示例: ### 一、open函数 #### 1. 函数原型与参数 ```c #include <fcntl.h> int open(const char *pathname, int flags, mode_t mode); ``` - **参数说明**: - `pathname`:文件路径(如`"a.txt"`) - `flags`:打开方式组合(必选项:$O_RDONLY$, $O_WRONLY$, $O_RDWR$;可选项:$O_CREAT$, $O_TRUNC$等) - `mode`:文件权限(当使用$O_CREAT$时需指定,如$S_IRUSR | S_IWUSR$) #### 2. 使用示例 ```c // 打开已存在文件(读写模式) int fd = open("test.txt", O_RDWR); if (fd == -1) { perror("文件打开失败"); } // 创建新文件(若不存在)并截断为0字节 fd = open("newfile.txt", O_RDWR | O_CREAT | O_TRUNC, 0644); ``` [^1][^2][^4] ### 二、write函数 #### 1. 函数原型与参数 ```c #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); ``` - **参数说明**: - `fd`:由$open()$返回的文件描述符 - `buf`:要写入的数据缓冲区 - `count`:写入字节数 #### 2. 使用示例 ```c char data[] = "Linux文件操作示例\n"; ssize_t bytes_written = write(fd, data, strlen(data)); if (bytes_written == -1) { perror("写入失败"); } else { printf("成功写入%zd字节\n", bytes_written); } ``` [^3][^4] ### 三、close函数 #### 1. 函数原型 ```c #include <unistd.h> int close(int fd); ``` - **作用**:释放文件描述符资源 #### 2. 使用示例 ```c if (close(fd) == -1) { perror("文件关闭失败"); } ``` ### 四、完整操作示例 ```c #include <fcntl.h> #include <unistd.h> #include <string.h> int main() { int fd = open("demo.txt", O_RDWR | O_CREAT, 0644); if (fd == -1) return -1; const char *content = "Hello Linux IO\n"; write(fd, content, strlen(content)); lseek(fd, 0, SEEK_SET); // 重置文件指针 char buffer[256]; ssize_t bytes_read = read(fd, buffer, sizeof(buffer)); if (bytes_read > 0) { printf("读取内容: %.*s", (int)bytes_read, buffer); } close(fd); return 0; } ``` [^4] ### 五、注意事项 1. **错误处理**:所有系统调用都应检查返回值(如$if (fd == -1)$) 2. **权限控制**:使用$O_CREAT$时必须指定$mode$参数(如$0644$表示`rw-r--r--`) 3. **文件描述符复用**:通过$lseek()$可调整读写位置 4. **系统调用与库函数**:$open()$是系统级API,而$fopen()$是C标准库函数[^5]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值