在C语言中,
open
、
write
和
read
函数是系统调用(system calls),它们直接由操作系统提供,用于底层的文件操作。这些函数是UNIX和类UNIX系统(如Linux)中的标准接口,不同于C标准库中的文件操作函数(如
fopen
、
fwrite
和
fread
)。
open
open函数用于打开一个文件或创建一个新文件,并返回一个文件描述符。这个函数在C语言的标准库中定义在<fcntl.h>头文件中。
#include<fcntl.h>int fd =open(constchar*pathname,int flags,mode_t mode);
pathname
:要打开的文件的路径。flags
:文件打开的模式标志,例如O_RDONLY
(只读)、O_WRONLY
(只写)、O_RDWR
(读写)、O_CREAT
(如果文件不存在则创建)等。mode
:文件创建时的权限模式,通常是一个三位八进制数,例如0666
表示读写权限。
返回值:
- 成功时返回一个文件描述符(非负整数)。
- 失败时返回
-1
,并设置errno
。
常见的 flags
O_RDONLY
:- 只读模式打开文件。- 文件描述符用于读取操作。O_WRONLY
:- 只写模式打开文件。- 文件描述符用于写入操作。O_RDWR
:- 读写模式打开文件。- 文件描述符可以用于读取和写入操作。O_CREAT
:- 如果文件不存在,则创建文件。- 需要提供mode
参数来设置文件权限(如果文件被创建)。O_TRUNC
:- 如果文件已存在且以写入模式打开,则截断文件为零长度(即清空文件内容)。O_APPEND
:- 以追加模式打开文件。- 写入数据时,数据将被追加到文件的末尾,而不是覆盖文件的现有内容。O_EXCL
:- 与O_CREAT
一起使用时,如果文件已经存在,则open
调用失败。- 用于确保文件的创建是唯一的。O_NONBLOCK
:- 以非阻塞模式打开文件。- 读写操作不会阻塞进程,适用于需要非阻塞操作的情况(如管道和套接字)。O_SYNC
:- 以同步模式打开文件。- 写入操作会在返回前确保数据被写入磁盘,适用于对数据持久性要求高的场景。O_DSYNC
:
- 以同步模式打开文件。不包括文件的元数据(如修改时间等)
- 由于 O_DSYNC 不涉及文件的元数据同步,它的性能开销通常低于 O_SYNC。这使得 O_DSYNC 更适合对数据持久性要求高但对元数据一致性要求相对较低的场景。
文件权限(mode)
当使用
O_CREAT
创建文件时,还需要指定文件权限(mode)。这是一个三位八进制数,表示文件的权限。例如:
- **
0666
**:文件的所有者、组和其他用户都有读写权限。 - **
0644
**:文件的所有者有读写权限,而组和其他用户只有读权限。 - **
0755
**:文件的所有者有读、写和执行权限,而组和其他用户只有读和执行权限。
权限模式由三个部分组成,分别表示文件的用户、组和其他用户的权限:
- 用户权限(Owner permissions):前两位(如
6
表示读写权限,4
表示读权限)。 - 组权限(Group permissions):中间两位。
- 其他权限(Other permissions):最后两位。
write
write
函数用于向文件写入数据。它在
<unistd.h>
头文件中定义。
#include<unistd.h>ssize_twrite(int fd,constvoid*buf,size_t count);
fd
:文件描述符,通过open
函数获得。buf
:指向要写入数据的内存区域的指针。count
:要写入的字节数。
返回值:
- 成功时返回实际写入的字节数。
- 失败时返回
-1
,并设置errno
。
read
read
函数用于从文件中读取数据。它同样在
<unistd.h>
头文件中定义。
#include<unistd.h>ssize_tread(int fd,void*buf,size_t count);
fd
:文件描述符,通过open
函数获得。buf
:指向用来存储读取数据的内存区域的指针。count
:要读取的字节数。
返回值:
- 成功时返回实际读取的字节数(可能小于
count
)。 - 返回
0
表示文件末尾。 - 失败时返回
-1
,并设置errno
。
lseek
lseek
是一个用于调整文件描述符的文件偏移量的系统调用。它可以在文件中设置读写操作的位置。以下是
lseek
的基本用法和参数说明:
off_tlseek(int fd,off_t offset,int whence);
fd
:文件描述符,通常由open
系统调用返回。offset
:新的偏移量值,具体含义取决于whence
参数。whence
:指定偏移量的起始位置,可以是以下三个常量之一: -SEEK_SET
:文件的起始位置。-SEEK_CUR
:文件当前的位置。-SEEK_END
:文件的末尾位置。
返回值
- 成功时,
lseek
返回新的文件偏移量。 - 失败时,返回
-1
并设置errno
以指示错误原因。
综合示例
#include<fcntl.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>intmain(){int fd =open("out.txt", O_RDWR | O_CREAT | O_TRUNC,0644);if(fd <0){perror("open");exit(EXIT_FAILURE);}// 写入数据constchar*message ="Hello World";ssize_t bytesWritten =write(fd, message,strlen(message));if(bytesWritten <0){perror("write");close(fd);exit(EXIT_FAILURE);}// 将文件描述符 fd 的偏移量设置到文件的开始位置if(lseek(fd,0,SEEK_SET)<0){perror("lseek");close(fd);exit(EXIT_FAILURE);}// 读取数据char buffer[20];ssize_t bytesRead =read(fd, buffer,sizeof(buffer)-1);if(bytesRead <0){perror("read");close(fd);exit(EXIT_FAILURE);}// 字符串要添加终止符
buffer[bytesRead]='\0';printf("%s\n", buffer);// 关闭文件close(fd);return0;}
版权归原作者 C or Cpp 所有, 如有侵权,请联系我们删除。