1. 文件I/O与标准I/O的区别
- 文件I/O又称为低级磁盘I/O,遵循POSIX相关标准【POSIX 表示可移植操作系统接口规范】。任何兼容POSIX标准的系统都支持文件I/O。
- 标准I/O又称为高级磁盘I/O,遵循ANSI C相关标准。只要开发环境中有标准C库,标准I/O就可以使用。
- 通过文件 I/O读写文件时,每次操作都会执行相关的系统调用。这样的好处是直接读写实际的文件,坏处是频繁的系统调用增加了系统的开销。
- 标准I/O可以看作是在文件I/O的基础上封装了一个缓冲机制,先读写缓冲区,必要的时候在访问实际文件,从而减少了系统调用的次数。
- 文件I/O中用文件描述符来表示打开一个文件,这个文件可以试不同类型的文件,而标准I/O中流表示一个打开的文件,通常只用来访问普通文件。
2. 文件和文件描述符
文件是以字符序列构成的信息载体
Linux操作系统是基于文件概念的,所以在Linux系统里有“一切皆文件”的说法,包括I/O设备。因此,与磁盘上的普通文件进行交互所用的同一系统调用可以直接用于I/O设备。。这样大大的简化了系统对不同设备的处理,提高了效率。
linux中的文件主要分为6种:
(1)普通文件
(2)目录文件
(3)符号链接文件
(4)管道文件
(5)套接字文件
(6)设备文件
文件描述符是被内核用来区分和引用文件的。对于Linux而言,所有对设备和文件操作都是通过文件描述符来进行的。
文件描述符是一个非负的整数,是一个索引值,并指向在内核中每个进程打开文件的记录表。当打开一个现存文件或创建一个新文件时,内核就会向进程返回一个文件描述符;读写文件时,需要把文件描述符作为参数传递给相应的函数。
基于文件描述符的I/O操作不能直接移植到类Linux以外的系统上去(Windows)。
它是实现一些I/O操作的唯一途径。如Linux中底层文件操作函数、多路I/O、TCP/IP套接字编程接口等。
3. 文件I/O 操作的相关API
3.1文件的打开
open()函数用于创建或打开文件,在打开或创建文件的同时可以指定文件打开的方式以及文件的访问权限。
int open(const char * pathname ,int flags , int perms);
- 头文件 :#include<sys/stat.h> #include<fcntl.h>
- 函数参数:
(1)pathname:被打开的文件名(可包括路径名)
(2)flags:文件的打开方式
(3)perms:创建新文件的存取权限(仅当创建新文件时使用) - 函数返回值:
(1)成功:文件描述符
(2)失败:-1
flags用与指定文件打开/创建模式,这个参数可由以下常量(定义于fcntl.h)通过逻辑位 或逻辑 “|” 构成。
-
打开文件至少得使用以下的三个常量的一个:
(1)O_RDONLY只读模式
(2)O_WRONLY只写模式
(3)O_RDWR读写模式 -
以下是可选用的:
(1)O_APPEND 每次写操作都写入文件的末尾
(2)O_CREAT 如果指定文件不存在,则创建这个文件
(3)O_EXCL 如果要创建的文件已经存在,则返回-1,并修改errno的值
(4)O_TRUNC 如果文件存在,并且以只读/写的方式打开,则清空文件的所有内容。
(5)O_NOCTTY 若打开的是终端文件,那么该终端不会成为当前进程的控制终端
若只选择了“O_WRONLY”或者“O_RDWR”则从文件第一个字节开始覆盖数据。
参数perms说明:即可用以下的宏定义法也可以用八进制表示法
3.2 文件的关闭
close()函数用于关闭一个被打开的文件。当一个进程终止时,所有打开的文件都由内核自动关闭。很多程序都利用这一特性而不显示的关闭一个文件。
int close(int fd);
- 头文件:#incldue<unistd.h>
- 函数参数:fd 文件描述符
- 返回值:
成功 :0
出错:-1
3.3文件的读写
read()函数从文件中读取数据储存到缓冲区中,并返回实际读取的字节数。
ssize_t read(int fd,void * buf ,size_t count);
- 头文件#include<unistd.h>
- 参数count:指定读出的字节数
- 返回值:
(1)成功:读到的字节数
(2)0:已到达文件末尾
(3)-1:出错
write()函数将数据写入到文件中,并返回实际写入的字节数。
ssize_t write(int fd, void buf ,size_t count);
- 头文件:#include<unistd.h>
- 返回值:
(1)成功:已写入的字节数
(2)出错:-1
3.4文件定位
lseek()函数对文件当前读写位置进行定位。它只能对可定位的文件操作。管道、套接字和大部分字符设备文件不支持此类操作。
off_t lseek(int fd, off_t offest, int whence);
-
头文件:#include<unistd.h> #inlcude<sys/types.h>
-
参数offest:偏移量
-
参数whence:基准值
(1)SEEK_END
(2)SEEK_CUR
(3)SEEK_SET -
返回值:
(1)成功:文件当前的位置
(2)出错:-1
总结
这几天呆在家里头都大了,疫情快点过去吧。