第二章 文件IO
问题:
- IO
- 文件描述符
- open close
- write read
- 文件偏移
1. IO?
- I : input
- O : outPut
说白了就是文件读写操作,Linux下,一切皆文件,文件是Linux系统设计思想的核心,所以对文件的IO操作很重要
2. 文件描述符
int fd1;
fd1 = open("./src_file", O_RDONLY);
上面的fd1即文件描述符(int类型),open成功返回一个 >0 的整数,Linux中所有打开的文件都会通过文件描述符索引
open打开或新建一个文件时,内核会向进程返回一个文件描述符,用于指代被打开的文件,所有执行IO操作的系统调用,都通过描述符来索引,如:
- ret = read(fd1, buff, sizeof(buff));
- ret = write(fd1, buff, sizeof(buff));
进程可以打开的文件描述符有数量限制:
ulimit -n查看
对于一个进程,文件描述符是一种有限的资源,从0开始分配
譬如:进程第一个打开的文件描述符是0,第二个是1…
当我们抵用open打开文件时,分配的文件描述符一般都是从3开始的(或者更大),因为:0、1、2已经被系统占用
- 0 : 标准输入(一般是键盘)
- 1: 标准输出(一般是LCD显示器)
- 2: 标准错误(一般是LCD显示器)
Linux系统中可以通过man命令查看某个系统调用的帮助信息,如:
man 2 open
- 1 linux命令
- 2 系统调用
- 3 C库函数
- flags
标志 | 用途 | 说明 |
---|---|---|
O_RDONLY | 只读打开 | |
O_WRONLY | 只写打开 | |
O_RDWR | 可读写 | |
O_CREATE | 如果文件不存在则新建 | |
O_DIRECTORY | 如果 pathname 参数指向的不是一个目录,则调用 open 失败 | |
O_EXCL | 此标志一般结合 O_CREAT 标志一起使用,用于专门创建文件。 在 flags 参数同时使用到了 O_CREAT 和O_EXCL 标志的情况下,如果 pathname 参数指向的文件已经存在,则 open 函数返回错误。 | 可以用于测试一个文件是否存在,如果不存在则创建此文件,如果存在则返回错误,这使得测试和创建两者成为一个原子操作;关于原子操作,在后面的内容当中将会对此进行说明 |
- mode
- O: Other(其他用户权限)
- G: Group(同组用户权限)
- U:文件所属用户权限
- S: 特殊权限
open
int fd = open("./app.c", O_RDWR)
if (-1 == fd)
return fd;
成功则返回文件描述符,失败返回-1
write
#include <unistd.h>
size_t write(int fd, const void *buf, size_t count);
返回:
0 : 未写入
< count : 这不是错误,有可能磁盘已满
-1 :错误
count : 写入成功
read
#include <unistd.h>
size_t read(int fd, void *buf, size_t count);
返回
读取成功,返回读到的字节数,实际读到的可能小于count,如:当前文件偏移量已经到了文件末尾前30字节,但是要求读100,则只会读取30字节,下次再读,就会返回0
close
#include <unistd.h>
int close(int fd);
关闭文件
返回:
- 0:成功
- -1:失败
除了使用close显式关闭,当一个进程终止时,也会自动关闭
lseek
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
参数
- offset: 偏移量(字节)
- whence: 定义offset的参考位置
– SEEK_SET:文件头开始计算offset
–SEEK_CUR: 偏移到当前位置偏移 + offset处
–SEEK_END:偏移到文件末尾 + offset
offset > 0 右偏
offset < 0 左偏