Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5518903
  • 博文数量: 922
  • 博客积分: 19333
  • 博客等级: 上将
  • 技术积分: 11226
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-27 14:33
文章分类

全部博文(922)

文章存档

2023年(1)

2020年(2)

2019年(1)

2017年(1)

2016年(3)

2015年(10)

2014年(17)

2013年(49)

2012年(291)

2011年(266)

2010年(95)

2009年(54)

2008年(132)

分类: LINUX

2011-12-27 10:02:04

++++++APUE读书笔记-03文件输入输出(1)++++++

 

简介
================================================
 我们以文件输入输出操作函数为开始,对UNIX系统进行讲解。文件输入输出函数包括:打开文件、读取文件、写文件等等。大多数UNIX系统上面的文件输入输出操作,都可以使用5个函数来完成:open,read,write,lseek,以及close。我们之后也会看到,对读写文件时候,设置不同的缓存大小会有什么效果。
 本章所述的函数一般都被称作无I/O缓冲的函数,和我们第5章所讲述的标准I/O函数相对。非缓冲的意思就是说,每次read或者write会产生内核中的一次系统调用。这些非缓冲的I/O函数并不是ISO C的一个部分,但是却是 POSIX.1 和 the Single UNIX Specification的一个部分。
 当我们讲到多进程之间的资源共享的时候,原子操作会变得非常重要。我们在讨论文件I/O以及open函数的参数的时候会对此进行讲述。这会就引出了多个进程之间如何共享文件,以及内核包含什么样的数据结构,这样的话题。讲述这些之后,我们会继续讲述dup,fcntl,sync,fsync和ioctl函数。

参考:


1、文件描述符号
================================================
 内核用文件描述符来引用所有打开文件。文件描述符是一个非负整数。当打开已有文件或创建新文件时,内核就向进程返回一个文件描述符。当读、写一个文件时,用open或creat返回的文件描述符标识该文件,将其作为参数传送给read或write。
 按照惯例,UNIX shell使用文件描述符0表示进程的标准输入,文件描述符1表示标准输出,文件描述符2表示标准错误输出。按照这个惯例,在POSIX.1应用程序中,幻数0、1、2应被代换成符号常数STDIN_FILENO,STDOUT_FILENO和STDERR_FILENO,这样能够提高程序的可移植特性。这些常数都定义在头文件中。另外,文件描述符的范围是0~OPEN_MAX(表示一个进程最多可以打开的文件数目),具体取值依据系统有所不同。
 后面将对基本文件操作函数做简单介绍,具体可以运行"man 2 "参见我们自己系统上的用户手册。

参考:


2、open函数
================================================
 调用open函数可以打开或创建一个文件。其具体声明如下:
 #include
 int open(const char *pathname, int oflag, ... /* mode_t mode   */ );
 返回:如果成功返回文件描述符号,如果错误返回1。
 (注意,这里出错的时候返回值为1,经过网上搜索发现,一般错误的时候,返回-1,也就是说,前面说的“如果错误返回1”中的“1”其实是布尔值,其实际值一般为-1,并且产生错误的时候,还会将错误编码记录到errno全局变量中。本书好多地方都这样说返回值,虽然简洁,但是可能会带来一些困扰所以读者应当注意,具体需要细究的时候,还需亲自查找手册上对错误情况返回值的说明)
 这里,第三个参数写为 “...”,这是ANSI C表示余下参数的数目和类型可以变化的方法。pathname是要打开或创建的文件的名字。oflag参数可用来说明此函数的多个选择项。
 oflag必须指定如下三个值之一:
 a)O_RDONLY   只读打开。
 b)O_WRONLY   只写打开。
 c)O_RDWR   读、写打开。
 下列常数则是可选择的:
 a)O_APPEND   每次写时都加到文件的尾端。
 b)O_CREAT   若此文件不存在则创建它。使用此选择项时,需同时指明第三个参数 mode,以说明该新文件的存取许可权位。
 c)O_EXCL   如果同时指定了O_CREAT,而文件已经存在,那么就出错。这样可以测试文件是否存在,不存在则创建,并且这个操作是原子的。
 d)O_TRUNC   如果此文件存在,而且为只读或只写方式打开,则将其长度截短为0。
 e)O_NOCTTY   如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端。
 f)O_NONBLOCK   如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,则本次打开操作和后续的 I / O操作设置非阻塞方式。
 g)O_SYNC   使每次write都等到物理I/O操作完成。
 由open返回的文件描述符一定是最小的没有使用的描述符数字。如果一个应用程序先关闭标准输出(通常是文件描述符1 ),然后打开另一个文件,那么就能知道该文件一定会在文件描述符1上打开,这个方法也是一个很常用的方法。后面讲到dup2函数时,会了解到有更好的方法来保证在一个给定的描述符上打开一个文件。
 当用append标记打开文件的时候,还是可以用lseek定位到任何地方来读取文件内容的,但是如果写的话,文件的offset会自动地定位到文件的结尾并且写。也就是说,用append的话,写操作不会写到除了结尾之外的地方(即使是用lseek定位也不会,这里的内容最好也参考原书3章13节,以及练习3.6)。

参考:


3、create函数
================================================
 也可用creat函数创建一个新文件。声明如下:
 #include
 int creat(const char *pathname, mode_t mode);
 返回:如果成功返回一个只写的文件描述符浩,如果错误返回1。
 此函数等效于:
 open(pathname,O_WRONLY|O_CREAT|O_TRUNC, mode)。

参考:

 

 

阅读(930) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~