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

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:当前值加offsetoffset可正可负
Whence=SEEK_END:文件长度加offsetoffset可正可负

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

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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值