posts - 403, comments - 310, trackbacks - 0, articles - 7
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

APUE - File I/O (1)

Posted on 2007-08-09 22:46 ZelluX 阅读(433) 评论(0)  编辑  收藏 所属分类: LinuxC/C++
1. unbuffered IO是相对于standard IO而言的,unbuffered指每个read和write函数都是通过内核系统调用实现的。这些函数并不是ISO C的一部分,但都属于POSIX.1和Single UNIX Specification.

2. File Descriptors
内 核中所有打开的文件都是通过File Descriptor指向的。file descriptor是一个非负的整数,按照管理,UNIX系统把0指定为进程的标准输入,1为进程的标准输出,2为标准错误输出。为了程序的通用性考 虑,这些magic number应该由<unistd.h>中的STDIN_FILENO, STDOUT_FILENO, STRERR_FILENO代替。
file descriptor的范围是从[0, OPEN_MAX],早期系统的上限为19,现在许多已经到达了63,Linux 2.4.22把每个进程打开的文件数上限提升到了2^20.

3. open 函数
#include <fcntl.h>
int open(const char *pathname, int oflag, ..., /* mode_t mode */ );
返回: 正常 - 最小的未被使用的file descriptor,出错 - 0
oflag: O_RDONLY(0), O_WRONLY(1), O_RDWR(2) 括号内为大多数情况下的值,这三个参数中必选一个,剩下的可选参数指定了是否追加、是否创建等信息,具体参见man 2 open

4. File Name and Pathname Truncation
如果创建的文件名长度大于NAME_MAX常量,BSD系统会返回一个错误状态,并把errno设为ENAMETOOLONG。如果只是把文件名截去部分就有可能导致与已存在的文件重名。
POSIX.1中的常量_POSIX_NO_TRUNC指定了长文件名和路径会被截断还是会引发错误

5.  创建文件
#include <fcntl.h>
int creat(const char *pathname, mode_t mode);
事实上这个函数等价于
open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);

6. 关闭文件
#include <fcntl.h>
int close(int filedes);
返回: 成功 -1,出错 0
当一个进程结束时,系统会自动关闭该进程打开的所有文件。

7. lseek 函数
每个打开的文件都有一个current file offset属性,通常是一个非负的整数。默认情况下文件打开后该值为0,除非指定了O_APPEND选项。
#include <unistd.h>
off_t lseek(int filedes, off_t offset, int whence);
// Returns: new file offset if OK, -1 on error

可以通过seek 0字节来得到当前的offset
off_t currpos;
currpos = lseek(fd, 0, SEEK_CUR);
这个方法也可以用来判断当前文件是否可以被seek,如果是指向管道(pipe),FIFO,或者socket的file descriptor,lseek把errno设置为ESPIPE并返回-1

某些设备可能允许负值的offset(如FreeBSD上的/dev/kmem),因此在检查返回值时应判断是否等于-1,而不是是否小于0

只有注册用户登录后才能发表评论。


网站导航: