不带缓存的文件I/O操作主要有5个函数open、read、write、lseek和close。这几个不带缓存的操作是指每个函数都调用内核中的一个系统调用。这些函数不是ANSIC组成部分,但属于POSIX的组成部分。
1.open函数
open 函数用于打开和创建文件.原型
此处)折叠或打开
- #inclue <fcntl.h>
- int open(const char *pathname, int flags, ... /* mode_t mode */)
返回值:成功则返回文件描述符,否则返回 -1
pathname 是待打开/创建文件的路径名(如 C:/cpp/a.cpp),相对或绝对路径。
flags :用于指定文件的打开/创建模式,这个参数可由以下常量(定义于 fcntl.h)通过逻辑或构成。
O_RDONLY 只读模式
O_WRONLY 只写模式
O_RDWR 读写模式
打开/创建文件时,用且只能用三个常量中的一个。以下常量是选用的:
O_APPEND 每次写操作都追加文件的末尾
O_CREAT 如果指定文件不存在,则创建这个文件 ,使用此选项时,要加第三个参数mode,指明文件访问权限
O_EXCL 如果要创建的文件已存在,则返回 -1,并且修改 errno 的值,,不存在则创建文件,用于测试文件是否存在
O_TRUNC 如果文件存在,并且以只写/读写方式打开,则将其长度截断为0
O_NOCTTY 如果路径名指向终端设备,则不要将该设备分配作为此进程的控制终端。
O_NONBLOCK 如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O设置为非阻塞模式(nonblocking mode)
以下三个常量同样是选用的,它们用于同步输入输出
O_DSYNC 使每次write等待物理 I/O 操作完成,在不影响读取新写入的数据的前提下,不等待文件属性更新。
O_RSYNC read操作等待所有写入同一区域的写操作完成后再进行
O_SYNC 每个write都等待物理 I/O 完成,包括包括由write引起的文件属性的跟新所需要的 I/O
第三个参数 (...)仅当创建新文件时才使用,用于指定文件的访问权限位(access permission bits)。
open 返回的文件描述符一定是最小的未被使用的描述符。
2. close函数
用于关闭已打开的文件,原型
此处)折叠或打开
- #include <unistd.h>
- int close(int fd);
返回值: 0(成功)或者 -1(出错)
fd: 是要关闭的文件描述符。
进程结束时,该进程打开的所有文件都会自动被内核(kernel)关闭。
关闭一个文件时,还会释放该进程加载该文件上的所有记录锁。
3.read函数
从打开文件中读数据,原型
此处)折叠或打开
- #include <unistd.h>
- ssize_t read(int fd,void *buf,size_t count);
返回值:成功,读到的字节数;0,已达文件尾;-1,出错.
fd: 文件描述符
buf: 指定存储器读出数据的缓冲区
count:指定读出的字节数
以下情况会导致读到的字节数小于count:
A. 读取普通文件时,读到文件末尾还不够 count字节。例如:如果文件只有 30 字节,而我们想读取 100 字节,那么实际读到的只有 30 字节,read 函数返回 30 。此时再使用 read 函数作用于这个文件会导致 read 返回 0 。
B. 从终端设备(terminal device)读取时,一般情况下每次只能读取一行。
C. 从网络读取时,网络缓存可能导致读取的字节数小于 count 字节。
D. 读取 pipe 或者 FIFO 时,pipe 或 FIFO 里的字节数可能小于 count 。
E. 从面向记录(record-oriented)的设备读取时,某些面向记录的设备(如磁带)每次最多只能返回一个记录。
F. 在读取了部分数据时被信号中断。
读操作从当前偏移量开始, 在成功返回之前,偏移量增加实际读取到的字节数。
4.write函数
向打开的文件写数据,原型
此处)折叠或打开
- #include <unistd.h>
- ssize_t write(int fd,const *buf,size_t count);
返回值:成功,已写入的字节数;-1,出错。
fd: 文件描述符
buf: 指定存储器写入数据的缓冲区
count:指定写入的字节数
对于普通文件,写操作始于偏移量 。如果打开文件时使用了 O_APPEND,则每次写操作都将数据写入文件末尾。成功写入后,偏移量增加,增量为实际写入的字节数。
5.lseek函数
所有打开的文件都有一个当前文件偏移量(current file offset),以下简称为 cfo。cfo 通常是一个非负整数,用于表明文件开始处到文件当前位置的字节数。读写操作通常开始于 cfo,并且使 cfo 增加所读写的字节数。文件被打开时,cfo 会被初始化为 0,除非使用了 O_APPEND 。
此处)折叠或打开
- #include <unistd.h>
- off_t lseek(int fd,off_t offset, int whence);
返回值:成功,文件的当前位移;-1,出错
fd: 文件描述符
offset: 偏移量,单位是字节的数量,可正可负(向前、向后移)
whence:
1. 如果 whence 是SEEK_SET,文件偏移量将被设置为 offset。
2. 如果 whence 是SEEK_CUR,文件偏移量将被设置为 cfo 加上 offset,offset 可以为正也可以为负。
3. 如果 whence 是SEEK_END,文件偏移量将被设置为文件长度加上 offset,offset 可以为正也可以为负。
lseek函数只修改文件表项中的当前文件偏移量,没有进行任何的I/O操作。
ps:文件名/路径名截短,当创建一个文件名长度超过NAME_MAX的文件时,Linux总是返回错误