Linux编程---I/O部分
Linux编程---I/O部分
很多函数都可以在网上找到,也比较基础,所以原型只给出了函数名.具体用到再man吧.
输入输出是个很重要的一块内容.几乎网络相关的东西基本都是靠底层IO调用来实现的.
好吧.还是先踏踏实实的介绍一下C标准库中的IO函数吧.个别函数我也是第一次见.对于不太常见的我就多解释一下,反正通常这些函数百度一下就清楚了,我就不多解释了~
推荐阅读:
Linux 多线程同步(信号量)
Linux C++动态链接库so编写
Linux多线程──主线程和子线程分别循环一定次数
Linux多线程──3个子线程轮流运行
Linux多线程──生产者消费者
Linux多线程──读者写者问题
Linux基础编程 多线程中的互斥锁 pthread_mutex_lock
Linux基础编程 多线程同步 pthread_cond_signal
1.C标准库IO函数
1.1流的关闭开启与重定向
fopen:打开一个流
fclose:关闭一个流
freopen:重新打开一个流
1.2 读与写
读:
fgetc getc getchar fgets gets getline getdelim fread
写:
fputc putc putchar fputs puts ungetc(这个叫读回退..写一个字符到输出缓冲流里) fwrite
1.3 文件定位
ftell :告诉文件指针的位置
fseek: 指定文件指针的位置
rewind: 将文件指针指向文件开头
fgetpos: 返回当前的文件指针的位置,并通过参数传回
fsetpos: 设置文件指针的位置
后面两个应该很少用吧..相对来说,一般都是通过相对位置来找,而不是绝对位置来找.
1.4 文件结束和错误指示器
ferror: 当且仅当流的错误指示器被设置,返回0
feof: 当到达文件结尾,结束条件指示器被设置,返回0
clearerr: 用于清除上面两个函数的指示器
这里的指示器是每个流对象内部的标志变量.没怎么用过这两个函数..不太清楚为什么要有clearerr这个函数..难道是为了忽略错误继续执行?
1.5 流缓冲
setbuf: 用于设置打开或关闭流的缓冲.这里的缓冲都是调用者提供的内存.
setvbuf: 这个除了指定哪里为缓冲外,还可以指定缓冲类型(全缓冲,航缓冲,无缓冲).
我想一般情况下用setbuf就行了吧~
说道流,就不得不提刷新了.特别是多线程的情况下.刷新是必备的~
fflush: 刷新流的缓冲区.
其实我也是才知道,在行缓冲下,换行符可以代替fflush~
1.6 格式IO
其实这个完全可以放到上面的读写当中去.但是书上是这么写的,所以我也这么总结吧.
输出: 格式为%[posp$][flags][width][.prec][size]fmt
printf fprintf sprintf
输入: 格式%[posp$][*][width][size]fmt
scanf fscanf sscanf
格式什么的对于C比较熟的我就不说明了.基本就是那些,如果记不起来的百度看看~
1.7 临时文件
tmpnam: 返回一个合法的临时文件名,这个文件一定在/tmp下建立.
tempnam: 功能比上面多一点,可以指定文件存放目录
tempfile: 可以避免竞争的创建临时文件(多线程同时使用tmpnam).进程结束自动关闭~
我还专门查了一下,发现标准C中是真有这个函数的.这对于运行中的进程来说很方便啊~
2. 低级IO
2.1 创建,关闭和打开文件
create open close
字面意思很明显了.所以用法就不多说了.这里关键是要了解打开文件后其在内核中管理的形式是如何的.
1) 这几个函数返回的都是一个int类型的值,叫做文件描述字.这个值是按最小未分配的文件描述字来优先分配的.所以你一开始打开了1号文件描述符,那么关闭之后,再打开其他文件,那么文件描述符就是1了.
2) 由于系统为了保证读写一致性的问题,会在内核中统一设立一个打开的文件表.并且每个流都有一个指向其表项的指针.然后每个系统打开文件表中,又有一个指针指向一个vnode的文件信息结点.
文件表项会记录文件的状态与文件指针位置信息,而vnode则只记录文件的基本信息(包括内容,文件大小和具体的磁盘上对应的记录位置,即包含inode上的信息).
虽然两个指针麻烦多了,不过这样分开之后,对于文件系统的要求就降低了.可以直接通过vnode这种统一的格式来操作文件呢.并且这个vnode是以文件打开才建立,而是针对每个文件,意思就是不同进程打开同一文件,必定使用相同的vnode.
3) 对于fork出来的子进程,所有的东西都会继承.所以也包含这个文件描述符和文件表项~
由于只复制进程中的资源,所以复制的是文件表项的指针~
2.2 读与写
read write
linux的函数写的真是太标准了....想让人望文生义都难啊...
这个我也就不多说了,具体的百度吧``
顺带附上lseek这个设置位置的函数.其实跟fseek差不多,所以也没什么好说的.
不过要注意这个函数返回off_t,而fseek返回int.
并且都可以把文件指针指向文件最大值之外,造成空洞.
2.3 重定向
dup: 复制描述字到一个新的描述字.即增加一个文件描述符描述同一个文件表项
dup2 把一个文件描述字所指的文件表项换成另一个文件描述字所指文件表项.即重定向
这个函数阐释了重定向的根本.只是修改文件描述符的指针所指向的文件表项.
2.4 文件描述符与流的转换
fdopen: 给它一个文件描述字,还你一个文件流!
fileno: 给它一个流,它就给你一个文件描述字
2.5 文件控制函数
fcntl: 对已打开的描述字进行操作.
其实就是修改文件表项中的信息.不过应该不止如此,书上还写有文件锁.所以我认为应该部分vnode内容也可以被修改.
具体用法也很多,主要有下面三条:
1) 重复文件描述字
2) 文件描述字标签,也就是包含描述字对应指针的那个结构体(这纯粹是我自己的理解,不对还请指正).
3) 文件状态标签.这个就多了.什么读写啊,追加啊,都可以通过这个函数更改和查看.
我自己也没怎么用过这个函数,毕竟不写库,文件的状态基本都是清楚的,没必要再改或者查询.
2.6 分散读和收集写
readv: 用于将自己文件中的连续信息,发到多个地址中去.
writev: 把多个地址的信息,写到自己的文件里面来.
这两个函数估计也就只有搞服务器开发的会用到了吧..
貌似UDP广播可以用这个实现.
2.7 清理内核IO缓冲区
fsync: 将文件修改的内容从内核缓冲区写到磁盘中去
fdatasync: 比上面功能好一点,只把修改过的数据写到磁盘中.所以一般比fsync块.
这里理一下.内核缓冲区也是分I和O的.对于O而言,用的是上面提到的输出缓冲.
关于I的部分.我个人认为很可能没有占用内核空间,而是直接用的read参数的地址.
当然,这还是得看了源码才知道是怎么回事.
更多详情见请继续阅读下一页的精彩内容:
|
评论暂时关闭