常用文件IO函数
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);
功能:
打开文件,如果文件不存在则可以选择创建。
参数:
pathname:文件的路径及文件名
flags: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。
参数:
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_RDWR : 读,写打开
这三个常量,必须指定一个且只能指定一个
O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
O_APPEND: 追加写
mode:这个参数,只有在文件不存在时有效,指新建文件时指定文件的权限
返回值:
成功:成功返回打开的文件描述符
失败:-1
close
#include <unistd.h>
int close(int fd);
功能:
关闭已打开的文件
参数:
fd : 文件描述符,open()的返回值
返回值:
成功:0
失败: -1, 并设置errno
当一个进程终止时,内核对该进程所有尚未关闭的文件描述符调用close关闭,所以即使用户程序不调用close,在终止时内核也会自动关闭它打开的所有文件。
read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:
把指定数目的数据读到内存(缓冲区)
参数:
fd : 文件描述符
buf : 内存首地址
count : 读取的字节个数
返回值:
成功:实际读取到的字节个数
失败: - 1
wride
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:
把指定数目的数据写到文件(fd)
参数:
fd : 文件描述符
buf : 数据首地址
count : 写入数据的长度(字节)
返回值:
成功:实际写入数据的字节个数
失败: - 1
文件描述符
文件描述符的本质是进程和被打开文件的的关系,操作系统中的每个进程多少都会打开几个文件,操作系统为了管理这些被打开的文件,当一个文件被打开时,操作系统会在内存要创建相应的数据结构file结构体来描述文件,这个结构体存储着被打开文件的大部分属性。
每个进程的test_struct(进程控制块)当中,包含着一个files_struct的结构体指针,指向一个这个进程的files_struct结构体,这个结构又做文件描述符表,用来记录文件描述符地使用情况,而在这个结构体中,又包含一个file* fd_array[] 的指针数组也叫做(文件描述符数组),每个元素都是一个指向打开文件的指针(file结构体的指针),数组的下标就是文件描述符,通过数组下标找到每个被打开的file结构体。
当进程打开一个文件文件时,操作系统会为这个文件创建一个file结构体,而在这个进程的files_struct数组中,找到当前没有被使用的最小下标,作为新的描述符。而每个进程的files_struct数组中,数组下标为0,1,2,分别对应这标准输入,标准输出,标准错误。
重定向
常见的重定向有<(输出重定向),>(输入重定向),>>(追加重定向)
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
int main()
{
close(1);
int fd=open("test.txt",O_RDWR |O_CREAT,0666);
if(fd<0){
perror("open");
}
write(1,"hello,world",11);
close(fd);
return 0;
}
当我们标准输出被关闭,在去open一个打开文件描述符时,被打开的就是1号文件描述符,当我们在去再去向标准输出写时,就会写向我们新打开的文件。
dup2
#include <unistd.h>
int dup2(int oldfd, int newfd);
功能:
通过 oldfd 复制出一个新的文件描述符 newfd,如果成功,newfd 和函数返回值是同一个返回值,最终 oldfd 和新的文件描述符 newfd 都指向同一个文件。
参数:
oldfd : 需要复制的文件描述符
newfd : 新的文件描述符,这个描述符可以人为指定一个合法数字(0 - 1023),如果指定的数字已经被占用(和某个文件有关联),此函数会自动关闭 close() 断开这个数字和某个文件的关联,再来使用这个合法数字。
返回值:
成功:返回 newfd
失败:返回 -1
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
int main()
{
int fd=open("test.txt",O_RDWR |O_CREAT,0666);
if(fd<0){
perror("open");
}
dup2(fd,1);
write(1,"hello,world",11);
close(fd);
return 0;
}
我们用dup2函数使fd覆盖掉了标准输出文件符,最后本该输出到屏幕的hello,world输出到test.txt里面。