码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-08-08 01:21:33      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

3.1 引言

文件I/O函数:打开文件,读文件,写文件

常用到五个函数:open, read, write, lseek, close.

本章描述的函数都是:不带缓冲的I/O(unbuffered I/O),属于不带缓冲 是指每个read和write都是调用内核中一个系统调用

3.2 文件描述符

对于内核而言,所有打开的文件都是通过文件描述符引用的

当读或写一个文件的时候,使用open或creat返回的文件描述符标示该文件,将其参数传给read或write

通常文件描述符0与标准输入关联,1与标准输出关联,2与标准错误关联,用STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO来提高可读性

3.3 函数open和openat

open和openat函数返回的文件描述符一定是最小未用的文件描述符

使用open或者openat创建或者打开一个文件

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

oflag参数可以用来说明此函数的多个选项,用下列一个或多个常量进行"或"运算构成oflag参数

O_RDONLY  只读打开 

O_WRONLY 只写打开
O_RDWR 读写打开  通常分别为0,1,2

O_EXEC 只执行打开

O_SEARCH 只搜索打开(应用与目录)

还有好多在APUE  P50

fd参数把open和openat函数去分开

(1) path参数指绝对路径,fd   可以被忽略open=openat

(2) path指相对路径,fd参数指出了相对路径名在文件系统中的起始地址.fd参数是通过打开相对路径文件名所在的文件目录获取的

(3) path指相对路径,fd参数具有特殊值AT_FDCWD, 这种情况下路径名再当前目录下获得

openat函数希望解决两个问题

(1) 让线程可以使用相对路径名打开目录中的文件,而不是只能打开当前工作目录

(2) 避免time-of-check-to-time-of-use(TOCTTOU)错误:该错误的基本思想是如果两个基于文件的函数调用,其中第二个调用依赖第一个调用的结果那么程序是脆弱的,因为一旦文件有变化,第二个调用的结构可能就不对了

文件名与路径名截断

如果NAME_MAX是14,而存在的文件名恰好是14个字符的文件,那么以路径名作为参数的任意函数讲无法知道文件的原始名是什么.其原因是这些函数无法判断函数是否被拦截过

现代文件系统支持文件名长度可以为255,因此对于绝大多数应用程序没有出过这样的问题

3.4 函数creat

可以使用creat创建一个新的文件

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

此函数等效于

open(path, O_ERONLY|O_CREAT|O_TRUNC, mode);

O_CREAT:此函数不存在的时候创建它

O_TRUNC:如果次文件存在,而且为只写或者读写成功打开,则将其长度截断为0

早期的UNIX系统版本中,open的第二个参数只能为0,1,2.无法打开一个尚未存在的文件,因此需要系统调用creat来创建一个文件

creat的一个不足之处是它只能以只写的方式创建文件.在提供open的新版本之前,如果想创建一个临时文件,然后再读这个临时文件,必须先调用creat,close然后再调用open,现在可以直接调用

open(path, O_RDWR|O_CREAT|O_TRUNC, mode);

这样用open可以直接创建一个可以读写的文件

3.5 函数close

可以调用close函数关闭文件

#include<unistd.h>
int close(int fd);
关闭一个文件时还会释放该进程加再该文件上的所有记录锁

当一个进程关闭时,内核将自动关闭进程所有打开的文件,很多程序都利用了这一功能而不显示的关闭文件

3.6 函数lseek

每个打开文件都有一个与其相关联的"当前文件偏移量"(current file offset),用来度量从文件开始初的字节数

通常读写操作都是从当前文件偏移量处开始

按系统默认的情况,当打开一个文件的时候,除非制定O_APPEND选项,否则文件偏移量处被设置为零

可以调用lseek显示地为一个打开文件设置文件偏移量

#include<unistd.h>
off_t lseek(int fd, off_t offset, int whence);
对参数offset的解释与参数whence的值有关,若执行成功返回新的文件偏移量,出错返回-1说明该文件不能设置偏移量

(1) whence 是SEEK_SET,将文件的偏移量设置为距文件开始处offset

(2) whence 是SEEK_CUP,将文件的偏移量设置为当前值加offset

(3) whence是SEEK_END,讲文件的偏移量设置为文件长度加上offset, offset可为正可为负

某些设备是允许偏移量为负数的,所以比较lseek返回值的时候必须要谨慎,不要测试是否小于0,而是是否等于-1

lseek仅将当前的文件偏移量记录在内核中,它并不引起任何的I/O操作.偏移量用于下一个读写操作

文件偏移量可以大于文件长度形成空洞,空洞不占用存储区

(未完待续)

版权声明:本文为博主原创文章,未经博主允许不得转载。

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

标签:

原文地址:http://blog.csdn.net/youngyangyang04/article/details/47345503

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!