UNIX 文件I/O总结

来源:互联网 发布:simon d 知乎 编辑:程序博客网 时间:2024/06/04 19:17

输入是从I/O设备拷贝数据到主存,输出是从主存拷贝数据到I/O设备。

一个文件就是一个字节序列。

所有的I/O设备,如网络、磁盘、和终端,都被模型化为文件,而所有的输入和输出都被当做想对应的文件的读写来执行。

1、ISO C的I/O操作是带缓存的,而POSIX标准的I/O操作是指真正发生了系统调用,是不带缓存的

2、文件描述

(1)是对一个已打开文件的引用,是由shell定义,Unix沿用,与内核无关。

(2)文件描述符是一个非负整数,0、1、2已被标准输入、标准输出和标准错误关联

(3)文件描述符是在某一个进程/线程中对一个文件的描述,同一个文件在不同进程/线程中的描述符可以不同,这也是文件共享的理论基础

3、文件打开操作 open()和openat()

(1)返回文件描述符或者-1

int open(char *filename, int flags, mode_t mode);
int openat(int fd,<span style="font-family: Arial, Helvetica, sans-serif;">char *filename, int flags, mode_t mode</span>)
(2)flags参数

 O_RDONLY: Reading only

O_WRONLY: Writing only

O_RDWR: Reading and writing 

还有O_APPEND、O_CREAT、O_SYNC等常用的参数。有需要参考官方文档。

(3)openat()的引入是为了解决 

open()中文件路径为相对路径时,不再只能打开当前工作目录的文件的问题

避免两个函数调用相关联引起的文件覆盖问题

fd为参数指出了相对路径在文件系统的起始地址

4、创建文件

int creat(const char *path,mode_t mode);等效于open(path,O_WRONLY|O_CREAT|O_TRUNC,mode)
creat()以只写的方式创建并打开文件,不能立即读取文件,所以最好用第二种方法。

5、文件关闭

int close(int fd);
关闭文件,释放记录锁。进程关闭时,内核会自动关闭该进程的所有调用文件,所以有时不比显示关闭文件。

6、文件偏移函数

off_t lseek(int fd,off_t offset, int whence);

whence:

SEEK_SET     文件操作从offset处开始

SEEK_CUR   文件已有偏移+offset

SEEK_END  文件长度+offset

offset 可正负

off_t的类型决定了一个文件的最大长度,32位时,有符号位,最大长度为2^31-1,2GB

7、读操作

ssize_t read(int fd, void *buf,size_t nbytes);

(1)返回-1,出错;返回0,到达文件末尾;返回正整数,读取字节数

(2)设置读取nbytes,在不同设备上可以读取的字节数往往不能满足nbytes

8、写操作

ssize_t write(int fd, void *buf,size_t nbytes);
(1)出错,返回-1,成功返回写的字节数

(2)默认写操作时从当前偏移开始的,但是当在打开文件设置了O_APPEND参数时,文件偏移设为了末尾,在末尾插入nbytes数据。

9、文件共享

(1)每个进程的进程表有一个表项记录打开文件的文件描述符表,不同的描述符,都对应一个不同的文件表

(2)文件表记录文件的状态(读、写、阻塞、同步、添加等)、文件偏移量和指向文件V结点结构的指针,仍然属于当前进程

(3)文件V结点结构是描述具体文件的信息载体。包含文件类型、对此文件的各种操作、文件作者、长度、指向文件所在磁盘位置的指针等。

文件V结点也是对具体文件系统的抽象,不属于某一个进程。

这样,不同进程可以对同一个文件V结点结构进行操作,在处理好同步的情况下,可以实现不同进程/线程的文件共享。

10、文件描述符的复制

共享同一个文件表

int dup(int fd);int dup2(int fd, int fd2);
dup()函数返回fd文件符描述文件的最小可用文件描述符,失败返回-1

dup2(fd,fd2)函数返回指定文件描述符fd2,如果fd2被占用,则先将其关闭,如果fd2=fd,返回fd2。失败返回-1。

11、缓存区刷新

延迟写:

内核中设有缓存区高速缓存或者页高速缓存,大多数I/O操作都要经过缓存区,再排入读写队列,最后由系统守护进程定时调用sync函数写入磁盘

void sync(void);int fsync(int fd);
sync将修改过的缓存区排入写队列,就返回,不管是否写入磁盘。写队列由系统守护进程update维护

fsync(fd)只将文件描述符fd描述的文件的修改部分立即调用I/O操作写入磁盘。

12、改变已打开文件的属性

int fcntl(int fd,int cmd,.../*int arg*/);
该函数有五种功能:

(1)辅助一个已有的描述符,功能同dup() dup2()函数

(2)获取/设置文件描述符的标志,即改变FD_CLOEXEC的值,0开,1关闭

(3)获取/设置文件状态

(4)获取/设置异步I/O的所有权

(5)获取/设置记录锁
13、ioctl函数

ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制。

详细参考:http://blog.csdn.net/shanshanpt/article/details/19897897





0 0
原创粉丝点击