前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >3(文件IO,不带缓冲的IO)

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

作者头像
提莫队长
发布2019-03-01 09:39:33
9200
发布2019-03-01 09:39:33
举报
文章被收录于专栏:刘晓杰刘晓杰

1 open函数

代码语言:javascript
复制
#include <fcntl.h>
int open(const char *pathname, int oflag,  /*mode_t mode*/ );

成功则返回文件描述符,失败则返回-1 第三个参数写成/*mode_t mode */ 表示这个参数仅在创建新文件时使用 Pathname表示要打开或者创建文件的名字 Oflag可用来说明此函数的多个选项。用下面一个或多个常量进行“或”运算构成

代码语言:javascript
复制
O_RDONLY            只读打开    0
O_WRONLY            只写打开    1
O_RDWR              读写打开    2

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

代码语言:javascript
复制
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

使用方法:

代码语言:javascript
复制
if ( ( fd = open( "file.hole" ,O_RDWR) ) < 0)
    err_sys( "open error" ) ;

2 create函数

代码语言:javascript
复制
#include <fcntl.h>
int creat(const char *pathname, mode_t mode);

它等效于

代码语言:javascript
复制
open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);

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

3 close函数

代码语言:javascript
复制
#include <unistd.h>
int close(int filedes);
    Returns: 0 if OK, 1 on error

4 lseek函数

代码语言:javascript
复制
#include <unistd.h>
off_t   lseek(int filedes, off_t offset, int whence);

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

代码语言:javascript
复制
Whence=SEEK_SET:距文件开始处的offset字节
Whence=SEEK_CUR:当前值加offset,offset可正可负
Whence=SEEK_END:文件长度加offset,offset可正可负

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

代码语言:javascript
复制
off_t currpos = lseek(fd, 0, SEEK_CUR);

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

代码语言:javascript
复制
#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函数

代码语言:javascript
复制
#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函数

代码语言:javascript
复制
#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函数)

代码语言:javascript
复制
#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函数(用来复制一个现存的文件描述符)

代码语言:javascript
复制
#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函数

代码语言:javascript
复制
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操作。 延迟写减少了磁盘读写,却降低了文件内容的更新速度次数,使得欲写到文件中的数据在一段时间内没写到磁盘上,如果系统发生故障,可能造成文件丢失

代码语言:javascript
复制
#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函数(可以改变已打开文件的性质)

代码语言:javascript
复制
#include <fcntl.h>
int fcntl(int filedes, int cmd, ... /* int arg */ );
        Returns: depends on cmd if OK , -1 on error

Fcntl函数有5种功能:

代码语言:javascript
复制
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)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年04月21日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 open函数
  • 2 create函数
  • 3 close函数
  • 4 lseek函数
  • 5 read函数
  • 3.8 write函数
  • 6 原子操作(pread和pwrite函数)
  • 7 dup和dup2函数(用来复制一个现存的文件描述符)
  • 8 延迟写
  • 9 fcntl函数(可以改变已打开文件的性质)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档