Linux的I/O操作方法:系统调用
系统调用由内核实现,在内核中执行,被程序(用户态)调用,区分于库函数的调用和实现,库函数的调用和实现、执行都在用户态
文件操作系统调用的头文件:<unistd.h>
1.打开文件
int open(const char *pathname, int flag, /*int mode*/);
pathname: 文件路径+文件名
flag:打开的标记
-
O_RDONLY 只读
-
O_WRONLY 只写
-
O_RDWR 读写
以上三个变量必须指定一个且只能指定一个。下列常量则是可选的:
-
O_APPEND 追加
-
O_CREAT 打开文件,不存在则创建
-
O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则会出错。用此可以测试一个文件是否存在
-
O_TRUNC 如果此文件存在,而且为只写或读写成功打开,则将其长度截取为0
-
O_NOCTTY 如果pathname指的是终端设备,则不将该设备分配作为此进程的控制终端
-
O_NONBLOCK 若pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,则此选项为文件的本次打开操作和后续的I/O操作设置为非阻塞模式
mode:只有flag为O_CREAT时,才需要该参数,指定创建的文件的访问权限,成功返回一个文件描述符(大于等于0的整数值),失败返回-1
返回值:成功返回一个文件描述符(大于等于0的整数值),失败返回-1
2.读取文件内容
int read(int fd, void *buf, int size);
fd:要读取的文件的文件描述符(用open打开的返回值)
buf:用户缓冲区,用于存储从文件中读取的数据
size:用户缓冲区的大小,指定一次read最多能够读取的数据长度,单位是字节
返回值:成功返回真实读到的数据长度,读到文件末尾返回0,读取失败返回-1
3.向文件中写入内容
int write(int fd, void *buf, int length);
fd:要写入的文件的文件描述符
buf:想写入文件中的数据的首地址
length:写入数据的长度
返回值:成功返回真实写入数据的长度,返回0没有写入任何内容,返回-1写入失败
4.操作读写游标(偏移量)
int lseek(int fd, int count, int flag);
fd:文件描述符
count:移动的大小
flag:相对位置
- SEEK_SET 将该文件偏移量设置为距离文件开始加count个字节,设置到文件头:lseek(fd, 0, SEEK_SET);
- SEEK_CUR 将该文件偏移量设置为距离当前偏移量加count个字节
- SEEK_END 将该文件偏移量设置为距离文件尾加count个字节
返回值:成功返回0,失败返回-1
5.关闭打开的文件
int close(int fd);
fd:要关闭的文件的文件描述符
返回值:成功返回0,失败返回-1
关闭一个文件会消除当前游标,下次打开游标在文件头
当一个进程终止时,内核自动关闭它所有打开的文件,很多程序都利用了这一功能而不显示地用close关闭打开的文件
6.例:用上述系统调用实现文件拷贝
void copyfile(const char *source, const char *dest)
{
int fdr = open(source,O_RDONLY);
assert(fdr != -1);
int fdw = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0664);//0664数字法设定文件权限
assert(fdw != -1);
while(1)
{
char buff[128] = {
0 };
int n = read(fdr, buff, 127);
if(n <= 0)
{
break;
}
write(fdw, buff, n);
}
close(fdr);
close(fdw);
}