知识点链接
https://www.yuque.com/aihenaobaijin/camuoq/lscmvf6z1arklau4?singleDoc# 《IO进程》
函数接口
打开文件open
O_RDONLY、O_WRONLY、O_RDWR、O_CREAT、O_TRUNC、O_APPEND
#include <fcntl.h>
int open(const char *pathname,int flags);
功能:打开文件
参数:pathname:文件路径名
flags:打开文件的方式
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写
O_CREAT:不存在创建
O_TRUNC:存在清空
O_APPEND:追加
返回值:成功:文件描述符
失败:-1
当第二个参数中有O_CREAT选项时,需要给open函数传递第三个参数,指定创建文件的权限
int open(const char*pathname,int flags,mode_t mode);
最后权限 = mode &(~umask)
例如:指定权限为0666(8进制)
最终权限=0666&(~umask)=0666&(~0002)=664
文件IO和标准IO的打开方式的对应关系
标准IO | 文件IO |
r 只读,当文件不存在时报错 | O_RDONLY 只读 |
r+ 可读可写,当文件不存在时报错 | O_RDWR 可读可写 |
w 只写,文件不存在创建,存在则清空 | O_WRONLY | O_CREAT | O_TRUNC,0777 只写,不存在创建,存在清空 |
w+ 可读可写,文件不存在创建,存在则清空 | O_RDWR | O_CREAT | O_TRUNC,0777 可读可写,不存在创建,存在清空 |
a 追加(在末尾写),文件不存在创建,存在追加 | O_WRONLY | O_CREAT | O_APPEND,0777 只写,不存在创建,存在追加 |
a+ 读和追加,文件不存在创建,存在追加 | O_RDWR | O_CREAT | O_APPEND,0777 可读可写,不存在创建,存在追加 |
注意:O_CREAT需要指定第三个参数表示权限
关闭文件close
#include <unistd.h>
int close(int fd);
功能:关闭文件
参数:fd:文件描述符
文件读写操作
读文件read()
ssize_t read(int fd,void *buf,size_t count);
功能:从一个已打开的可读文件中读取数据
参数: fd 文件描述符
buf 存放位置
count 期望的个数
返回值:成功:实际读到的个数(小于期望值说明实际没这么多)
返回0:表示读到文件结尾
返回-1:表示出错,并设置errno号
写文件write
ssize_t write(int fd,const void *buf,size_t count);
功能:向指定文件描述符中,写入 count个字节的数据。
参数:fd 文件描述符
buf 要写的内容
count 期望写入字节数
返回值:成功:实际写入数据的个数
失败 :-1
文件定位操作
off_t lseek(int fd,off_t offset,int whence);
功能:设定文件的偏移位置
参数:fd:文件描述符
offset: 偏移量
正数:向文件结尾位置移动
负数:向文件开始位置
whence: 相对位置
SEEK_SET 开始位置
SEEK_CUR 当前位置
SEEK_END 结尾位置
补充:和fseek一样其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2
返回值:成功:文件的当前位置
失败:-1
编程练习
练习1:文件IO实现cp功能 cp 源文件 目标文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define N 1024
int main(int argc, char const *argv[])
{
int fd1, fd2, n;
char buf[N];
if (argc != 3)
{
printf("usage:%s <file1> <file2>\n", argv[0]);
return -1;
}
if ((fd1 = open(argv[1], O_RDONLY)) == -1)
{
perror("open fd1 error");
return -1;
}
if ((fd2 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1)
{
perror("open fd2 error");
return -1;
}
while ((n = read(fd1, buf, N)) > 0)
{
write(fd2, buf, n);
}
close(fd1);
close(fd2);
return 0;
}
练习2:向文件中第 10 位置后面写一个字符,在文件此时的位置,往后移动20个位置处,写一行字符串hello进去,求此时文件的长度
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
int fd;
if (argc != 2)
{
printf("usage:%s<filename>\n", argv[0]);
return -1;
}
fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC);
if (fd < 0)
{
perror("open error");
return -1;
}
lseek(fd, 10, 0);
write(fd, "k", 1);
lseek(fd, 20, 1);
write(fd, "hello", 5);
off_t off = lseek(fd, 0, SEEK_END);
printf("%ld\n", off);
return 0;
}