3.1 不带缓冲的I/O:open,read,write,lseek,close。不是ISO C的组成部分,但是是POSIX.1和Single UNIX Specification的。 3.2 文件描述符,0=stdin,1=stdout,2=stderr。进程打开文件的最大值OPEN_MAX(0~19)20个,限制很多是(0~63)64个。 3.3 int open(const char *pathname, int flags/*, mode_t mode*/); 3.4 int creat(const char *pathname, mode_t mode); 等价于open(pathname, O_WRONLY|O_CREAT|O_TRUNC, mode);只写模式。 3.5 int close(int filedes);关闭文件会释放该进程加在文件上的所有记录锁。 3.6 off_t lseek(int filedes, off_t offset, int whence);测试返回值,不要测试是否小于0,而要测试是否等于-1。 SEEK_SET,文件开始位置+offset。 SEEK_CUR,文件当前偏移+offset。可正可负。 SEEK_END,文件末尾+offset。可正可负。 lseek仅将当前的文件offset记录在内核中,不会引起任何I/O操作。 3.7 ssize_t read(int filedes, void *buf, size_t nbytes);返回读到的字节,总是<=buffer size。 3.8 ssize_t write(int filedes, const void *buf, size_t nbytes);返回值通常与参数nbytes相同,否则表示出错。 3.9 I/O效率,Linux ext2,buffer大小4096时CPU时间最小值出现。大多数文件系统采用某种预读(read ahead)改善性能。 3.10 内核使用三种数据结构表示打开的文件。 1)每个进程在进程表中都有一个记录项,记录项中包含打开文件的描述符表,每个描述符占用一项。 2)内核为打开文件维持一张文件表。表中有(文件状态,文件偏移,v节点指针) 3)每个打开文件都有一个v节点结构。 两个独立进程各自打开同一文件,则每个进程都得到一个文件表项,但对给定的文件只有一个v节点表项。 3.11 打开文件时使用O_APPEND会使操作称为原子操作。 pread,pwrite是Single UNIX Specification的XSI扩展,是原子操作。 open函数中指明标记O_EXCL,则也是原子操作。(其实就是独占打开)。 3.12 int dup(int filedes); 用来复制现存的文件描述符。 int dup2(int filedes, int filedes2); dup返回的是最小可用file des。用dup2可以用filedes2指定新的描述符。如果filedes2已经打开,则会将其关闭。如果filedes等于filedes2,则dup2返回filedes2,而不关闭它。 3.13 int fsync(int filedes);即刻更新指定文件。 int fdatasync(int filedes);即刻更新文件的数据部分,但不包括文件属性等。 void sync(void); 将修改的块缓冲区入队,然后返回,不等待实际写磁盘操作结束。update daemon一般30秒会调用该函数。 3.14 int fcntl(int filedes, int cmd, .../* int arg */ );改变打开的文件性质。 复制现有描述符(cmd=F_DUPFD) 获取/设置文件描述符标记(cmd=F_GETFD或F_SETFD) 获取/设置文件状态标记(cmd=F_GETFL或F_SETFL) 获取/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN) 获取设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW) 3.15 ioctl,I/O操作的杂物箱。 3.16 /dev/fd/目录。