linux文件io

踏入了阶段四

在 Linux 系统下,用于对文件操作的库函数叫做 文件 I/O
主要包括 open()/close()/read()/write() /lseek()相应的系统调用(准确说法是对系统调用的封装的库函数)

文件描述符

文件描述符(file descriptor)是一个非负整数,当打开或者创建一个文件时内核向进程返回一个文件描述符。
每个程序运行后,操作系统会默认打开三个文件 标准输入 标准输出 标准错误输出,文件描述符分别为 0 , 1 , 2

open函数

int open(const char *pathname, int flags, mode_t mode);
open函数的返回值就是打开该文件的fd,pathname就是文件路径名
flags : 打开标志
O_RDONLY:只读方式打开文件
O_WRONLY:可写方式打开文件
O_RDWR:读写方式打开文件
O_CREAT:如果该文件不存在就创建一个新的文件,并用第三的参数为其设置权限
O_EXCL:如果使用O_CRATE时文件存在,open()报错
O_TRUNC:如果文件已经存在,并且以读/写或只写成功打开,并清零
O_APPEND: 以添加的方式打开文件,在打开文件的同时,文件指针指向文件末尾
注意:比如我要以只写的方式打开文件,如果不存在则创建,如果文件存在则截短,那么我可以用到位运算O_WRONLY|O_CREAT|O_TRUNC
mode :
指定创建新的文件的默认权限

像上文说到如果成功的话返回fd,如果失败的话返回 -1,并将错误编码保存到 errno。
errno 是 Linux 操作系统中用于存储错误编码的全局变量但是用编码来看不方便,我们可以将错误信息打印:
错误信息打印主要使用 perror() 函数

1
void perror(const char *s)

close 函数

1
int close(int fd);

作用: close 函数用于关闭文件,在 io 操作结束后需要关闭文件,释放相关资源
成功 : 返回 0

失败 : 返回 -1

打开后用完记得要关闭.


read函数

ssize_t read(int fd, void *buf, size_t count);

参数buf是指定的缓冲区,count是能够读取的最大字节数。一般定义缓冲区的时候以32,64,128大小定义,比如char buf[64]
返回值:
成功 : 返回实际读取的字节数

失败 : -1,并将错误编码设置到 errno 中


write函数

ssize_t write(int fd, const void *buf, size_t count);

返回值:
成功 : 返回实际读取的字节数

失败 : -1,并将错误编码设置到 errno 中

写入的话记得不要多写,不然可能会出现问题


lseek函数

当我们在open一个文件后write写入,然后read读取,会发现读取的不是我们想要的write内容,这是因为所有打开的文件都有一个当前文件偏移量(current file offset)。cfo 通常是一个非负整数,用于表明文件开始处到文件当前位置的字节数。
读写操作通常开始于 cfo,并且使 cfo 增大,增量为读写的字节数。

off_t lseek(int fd, off_t offset, int whence);

返回值:
成功: 返回 0
失败 : 返回 -1,并设置 errno
函数参数
fd : 文件描述符
offset :偏移量,可以为正数或者负数
whence :偏移相对位置
SEEK_CUR : 相对于文件当前偏移
SEEK_SET : 相对于文件开始位置
SEEK_END : 相对于文件尾偏移

如果要把写入的东西读取出来要

lseek(fd,0,SEEK_SET);


练习 : 使用 Linux 文件 io 接口实现 文件复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char *argv[])
{
ssize_t rdbytes;
ssize_t wrbytes;
int fd,fd_dest;
//打开要读取的文件
fd=open(argv[1],O_RDONLY);
//打开要写入的文件dest.txt
fd_dest=open(argv[2],O_RDWR);
//建立缓冲区
char R_buffer[64]={0};
if(fd==-1)
{
perror("open():");
return -1;
}
while(rdbytes!=0)
{
rdbytes=read(fd,R_buffer,1);
if(rdbytes==-1)
{
perror("read():");
return -2;
}

//写入
wrbytes=write(fd_dest,R_buffer,strlen(R_buffer));
if(wrbytes==-1)
{
perror("write();");
return -3;
}


}
close(fd);
close(fd_dest);
return 0;


}
Contents
  1. 1. 踏入了阶段四
  2. 2. 文件描述符
    1. 2.1. open函数
    2. 2.2. close 函数
    3. 2.3. read函数
    4. 2.4. write函数
    5. 2.5. lseek函数