UNIX环境高级编程-第3章- 文件I/O

3.1 引言

        文件I/O可分为两类:第一类是非缓冲式的文件操作;该类型一般由系统调用,主要函数有open,write,read,lseek,close;第二类是缓冲式文件操作;该类型由标准输入输出提供操作;本文记录的是第一类文件I/O。

3.2 文件描述符

       内核通过文件描述符打开的文件,它是一个非负整数。通常,文件描述符0对应标准输入;文件描述符1对应标准输出;文件描述符2对应标准出错。依照POSIX,这些整数应替换为符号常量 STDIN_FILENO 、 STDOUT_FILENO 、 STDERR_FILENO ,定义在 <unistd.h> 中。

 3.3 open函数

/*
*函数功能:打开或创建一个文件;
*返回值:若打开成功返回文件描述符,若出错则返回-1;
*/
/*
*函数原型:
*/
#include <fcntl.h>
 
int open(const char* pathname, int oflag);
int open(const char* pathname, int oflags,mode_t mode);
 
/*
*参数解释:
*pathname是打开或创建的文件名称;
*oflag只能是下面三个中的一个或与其它选项组成:
*只能指定一个:O_RDONLY(只读),O_WRONLY(只写),O_RDWR(可读写)
*其它选项:
*O_APPEND     :写操作追加到文件尾
*O_CREAT        :若打开的文件不存在,则创建,需要使用第三个参数mode
*O_EXCL           :测试文件是否存在,不存在则创建此文件
*O_TRUNC       :若文件存在,且只写或读写打开,则将文件长度截取为0
*O_NOCTTY     :若文件名称pathname是终端设备,则该设备不能作为进程控制的终端
*O_NONBLOCK        :如果pathname值的是一个FIFO,一个块特殊文件或一个字符特殊文件,则此选项为文件的本次打开操作和后续的I/O操作设置非阻塞模式。
*mode是提供新建文件的权限,选项有O_CREAT时必须需要mode参数
*/

3.4 creat函数

creat函数
/*
*函数功能:创建一个新文件;
*返回值:若创建成功则返回只写文件描述符,若出错则返回-1;
*/
/*
*函数原型:
*/
#include <fcntl.h>
 
int creat(const char* pathname, mode_tmode);
/*等效于:open(pathname,O_WRONLY| O_CREAT | O_TRUNC, mode);*/
 
/*
*参数解释:
*pathname是打开或创建的文件名称;
*mode是提供新建文件的权限,选项有O_CREAT时必须需要mode参数
*/

3.5 close函数

close函数
/*
*函数功能:关闭一个已经打开的文件;同时会释放所有进程加载该文件的记录锁;
*返回值:若关闭成功返回0,若出错则返回-1;
*/
/*
*函数原型:
*/
#include <unistd.h>
 
int close(int filedes);
 
/*
*参数解释:
*filedes已打开的文件描述符;
*/


3.6 lseek函数

/*
*函数功能:当前文件偏移量;
*返回值:若成功返回新的文件偏移量,若出错则返回-1;
*/
/*
*函数原型:
*/
#include <unistd.h>
 
off_t lseek(int filedes, off_t offset, intwhence);
 
/*
*参数解释:
*filedes是文件描述符;
*offset表示偏移字节数;
*whence参数有一下三种:
*SEEK_SET        :表示偏移量设置为文件开始处的offset个字节;
*SEEK_CUR      :表示偏移量设置为当前值加offset个字节;
*SEEK_END      :表示偏移量设置为文件长度加offset个字节;
*/

3.7 read函数

/*
*函数功能:读取已打开文件的数据;
*返回值:若成功返回读取的字节数,若到文件尾则返回0,若出错则返回-1;
*/
/*
*函数原型:
*/
#include <unistd.h>
 
ssize_t read(int filedes, void *buf, size_tnbyte);
 
/*
*参数解释:
*filedes是指所要读取文件的文件描述符;
*buf存储所读取数据;
*nbyte表示最多读取的字节数;
*/

3.8 write函数

/*
*函数功能:向已打开文件写入数据;
*返回值:若成功返回已写的字节数,若出错则返回-1;
*/
/*
*函数原型:
*/
#include <unistd.h>
 
ssize_t write(int filedes, const void *buf,size_t nbyte);
 
/*
*参数解释:
*filedes是指所要写入数据文件的文件描述符;
*buf存储所要存储的数据;
*nbyte表示最多写入的字节数;
*/

3.10 文件共享

    UNIX支持不同进程共享打开的文件。内核使用三种数据结构表示打开的文件:

进程在进程表中都有一个记录项,记录项中包含一张打开文件的描述符表。每个描述符占一项:描述符标志fd;指向一个文件表项的指针。

内核维持一张所有打开文件的文件表,每个文件表项包含文件状态标志、当前文件偏移量、指向文件v节点表项的指针。

每个打开文件有一个v节点表,每个v节点包含文件类型、操作函数指针和文件的i节点等。

        Linux将v节点和i节点实现为独立于文件系统的i节点和依赖文件系统的i节点。

       不同进程共享文件时,每个进程都有一个该文件的文件表项,指向同一个v节点表。多个文件描述符也可能指向同一个文件表项,如使用 dup 函数和 fork 后的父子进程。以下是不同进程共享同一个文件的示意图:



3.11 原子操作

         原子操作指由多步组成的操作,执行时要么全部执行,要么一步也不执行。
       多个进程共享同一个文件,可能造成进程对文件的连续的操作被打乱,这就需要使操作成为原子操作。如 O_APPEND 将到尾端和写入数据组成原子操作,还有 O_CREAT 和 O_EXCL 将检查文件是否存在和创建文件组成原子操作。例如:pread 和 pwrite 将偏移量和读/写组成原子操作。

pread 和 pwrite 函数

#include <unistd.h> 
/* 函数功能:定位并读取数据
* 返回值:成功返回读到的字节数,已到文件尾则返回0,出错返回-1 ;
*/
ssize_t pread(int fd, void *buf, size_tcount, off_t offset);
/* 函数功能:定位并写入数据
* 返回值:成功返回写入的字节数,出错返回-1;
*/
ssize_t pwrite(int fd, const void *buf,size_t count, off_t offset);

3.12 dup函数

/*
*函数功能:复制已有的文件描述符;
*返回值:若成功返回当前可用的文件描述符最小值,若出错则返回-1;
*/
/*
*函数原型:
*/
#include <unistd.h>
 
int dup(int filedes);
 
/*
*参数解释:
*filedes是指当前文件的文件描述符;
*/
 
dup2函数
/*
*函数功能:复制已有的文件描述符;
*返回值:若成功返回参数filedes2指定的文件描述符,如果filees2已经打开,则现将其*关闭,如果filedes1等于filedes2,则返回filedes2,不关闭;若出错则返回-1;
*/
/*
*函数原型:
*/
#include <unistd.h>
 
int dup2(int filedes1,intfiledes2);
 
/*
*参数解释:
*filedes是指当前文件的文件描述符;
*/

3.13 刷新缓冲区函数

unix系统在写数据时是采用文件延迟写,但是我们可以自己刷新缓冲区,将数据写入磁盘。以下是刷新缓冲区,将数据写入磁盘的函数sync,fsync,fdatasync;
#include <unistd.h>
 
/* 将所有修改过的块缓冲区排入写队列,然后返回,不等待写磁盘结束 */
void sync(void);
 
/* 对指定文件刷新块缓冲区,等待写磁盘结束,更新文件属性
* 返回值:成功返回0,出错返回-1 */
int fsync(int fd);
 
/* 对指定文件刷新块缓冲区,等待写磁盘结束,不更新文件属性
* 返回值 成功返回0,出错返回-1 */
int fdatasync(int fd);

3.14 fcntl函数

/*
*函数功能:可以改变已打开文件的性质。
*函数原型:
*/
#include <unistd.h>
#include <fcntl.h>
/*
 * 返回值:成功依赖于cmd,出错返回-1
*/
int fcntl(int filedes, int cmd, ... /*intarg */ );
/*
*参数解释:
*filedes表示文件描述符;
*cmd参数,根据 cmd 值的不同,有以下5种功能:
*
*(1)F_DUPFD ,复制一个现有的描述符。新描述符为大于等于 arg 的最小可用值。
*(2)F_GETFD 、 F_SETFD ,获取/设置文件描述符标记。文件描述符标志只有 FD_CLOEXEC ,但一般使用0或1,分别代表 exec 时不关闭或关闭,0为默认值。
*(3)F_GETFL 、 F_SETFL ,获取/设置文件状态标志。可获取的文件状态标志见 open 函数的 flags 可取值,可设置的文件状态标志不包括访问模式位和创建模式位。
*(4)F_GETOWN 、 F_SETOWN ,获取/设置异步I/O所有权,即接收 SIGIO和 SIGURG *信号的进程ID或进程组ID, arg 为正为进程ID, arg 为负为等于其绝对值的进程组ID。
*(5)F_GETLK 、 F_SETLK 、 F_SETLKW ,获取/设置记录锁。
*agr是指定的整数值;
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值