您的位置:首页 > 其它

3(文件IO,不带缓冲的IO)

2016-04-21 09:54 330 查看

1 open函数

#include <fcntl.h>
int open(const char *pathname, int oflag,  /*mode_t mode*/ );


成功则返回文件描述符,失败则返回-1

第三个参数写成/*mode_t mode */ 表示这个参数仅在创建新文件时使用

Pathname表示要打开或者创建文件的名字

Oflag可用来说明此函数的多个选项。用下面一个或多个常量进行“或”运算构成

O_RDONLY            只读打开    0
O_WRONLY            只写打开    1
O_RDWR              读写打开    2


上面三个常量必须且只能指定一个。下面的常量是可选的

O_APPEND    每次写时都追加到文件的尾端
O_CREAT     若此文件不存在则创建它,使用此项时需要第三个参数mode
O_EXCL      可以测试文件是否存在,若不存在则创建,这使得测试和创建成为原子操作
O_TRUNC     如果此文件存在,而且为只写或读写成功打开,则将其长度截短为0
O_NOCITY    如果pathname指的是终端设备,则不将该设备分配为控制终端
O_NONBLOCK  如果pathname指的是一个FIFO,一个块特殊文件或一个字符特殊文件,则将本次打开及后续操作设置为非阻塞模式
O_DSYNC     使每次write等待物理I/O操作完成
O_RSYNC     使read操作等待,直至写操作完成
O_SYNC      使每次write等待物理I/O操作完成,包括由write操作引起的文件属性更新所需的I/O


使用方法:

if ( ( fd = open( "file.hole" ,O_RDWR) ) < 0)
err_sys( "open error" ) ;


2 create函数

#include <fcntl.h>
int creat(const char *pathname, mode_t mode);


它等效于

open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);


成功则返回为只写打开的文件描述符,失败则返回-1

3 close函数

#include <unistd.h>
int close(int filedes);
Returns: 0 if OK, 1 on error


4 lseek函数

#include <unistd.h>
off_t   lseek(int filedes, off_t offset, int whence);


若成功返回新的偏移量,失败返回-1

Whence=SEEK_SET:距文件开始处的offset字节
Whence=SEEK_CUR:当前值加offset,offset可正可负
Whence=SEEK_END:文件长度加offset,offset可正可负


可以用以下方式确定打开文件的当前偏移量

off_t currpos = lseek(fd, 0, SEEK_CUR);


由于不成功时返回-1,所以一定要和-1比较。因为某些设备也允许负的偏移量

#include "apue.h"
Int main(void)
{
if (lseek(STDIN_FILENO, 0, SEEK_CUR) == -1)
printf("cannot seek\n");
else
printf("seek OK\n");
exit(0);
}


5 read函数

#include <unistd.h>
ssize_t read(int filedes, void *buf, size_t nbytes);
Returns: number of bytes read, 0 if end of file, -1 on error


3.8 write函数

#include <unistd.h>
ssize_t write(int filedes, const void *buf, size_t nbytes);
Returns: number of bytes written if OK, -1 on error


6 原子操作(pread和pwrite函数)

#include <unistd.h>
ssize_t pread(int filedes, void *buf, size_t nbytes, off_t offset);
Returns: number of bytes read, 0 if end of file, 1 on error
ssize_t pwrite(int filedes, const void *buf, size_t nbytes, off_t offset);
Returns: number of bytes written if OK, 1 on error


调用pread相当于调用lseek和read,但是pread又和这种顺序有重要区别:

一.调用pread时,无法中断其定位和读操作

二.不更新文件指针

调用pwrite相当于调用lseek和write

7 dup和dup2函数(用来复制一个现存的文件描述符)

#include <unistd.h>
int dup(int filedes);
int dup2(int filedes, int filedes2);
Both return: new file descriptor if OK, -1 on error


Dup()返回的新描述符一定是最小数值,而dup2()可以通过filedes2来指定新的描述符

复制一个描述符的另一种方法是fcntl函数

dup2(filedes, filedes2);等效于dup(filedes);
fcntl(filedes, F_DUPFD, filedes2);等效于dup2(filedes, filedes2);


当然了,dup2并不完全等同于close和fcntl. 原因有两点

1.dup2是原子操作,而close和fcntl则包括两个函数调用。有可能在close和fcntl之间插入执行信号捕捉函数,它可能修改文件描述符

2.dup2和fcntl有某些不同的errno

8 延迟写

当数据写入文件时,先将数据复制到缓冲区中。如果缓冲区没写满,则等待缓冲区写满或者需要存放其他磁盘块数据时,再排入输出队列,待其到达队首时,才进行实际的I/O操作。

延迟写减少了磁盘读写,却降低了文件内容的更新速度次数,使得欲写到文件中的数据在一段时间内没写到磁盘上,如果系统发生故障,可能造成文件丢失

#include <unistd.h>
int fsync(int filedes);
int fdatasync(int filedes);
Returns: 0 if OK, 1 on error
void sync(void);


sync是对所有文件起作用,将所有修改过的块缓冲,排入写队列,但是不等待写完成即返回;fsync只对文件描述符filedes指定的单一文件起作用,并且等待写磁盘操作结束;fdatasync类似于fsync,但它只影响文件的数据部分,fsync还会同步更新文件的属性

9 fcntl函数(可以改变已打开文件的性质)

#include <fcntl.h>
int fcntl(int filedes, int cmd, ... /* int arg */ );
Returns: depends on cmd if OK , -1 on error


Fcntl函数有5种功能:

Duplicate an existing descriptor (cmd = F_DUPFD)
Get/set file descriptor flags (cmd = F_GETFD or F_SETFD)
Get/set file status flags (cmd = F_GETFL or F_SETFL)
Get/set asynchronous I/O ownership (cmd = F_GETOWN or F_SETOWN) 异步I/O所有权
Get/set record locks (cmd = F_GETLK, F_SETLK, or F_SETLKW)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: