Chinaunix首页 | 论坛 | 博客
  • 博客访问: 165241
  • 博文数量: 43
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 675
  • 用 户 组: 普通用户
  • 注册时间: 2013-01-26 00:58
文章分类
文章存档

2014年(2)

2013年(41)

我的朋友

分类: C/C++

2013-08-23 20:10:20

第三章 文件 IO


1.标志分为:文件状态标志GETFL 文件描述符标志GETFD

这三种值互斥一个文件只能有这三种值之一。 )因此首先必须用屏蔽字 O_ACCMODE取得存取方式位,然后将结果与这三种值相比较。



2.linux下管道的执行顺序不同。比如 a | b 大多数貌似是shell → fork → exec b → fork exec a. a 标准输入为b标准输出。(这里不同的继承顺序决定于不同的实现,见APUE9.9



3.打开文件/dev/fd/n等效于复制描述符 n (假定描述符n是打开的)


4.readwrite没有缓冲功能指的是在用户空间,实际上在进行该系统调用的时候在系统内是有缓冲区的。(不然一个个往磁盘上写啊)

freadfopen的优势在于,函数自动在用户空间提供缓冲区,减少了系统调用的次数,也就减少了管态和模态的切换时间。




第一个问题:二进制文件和文本文件。

第一,以二进制和文本方式打开在linux下并无区别,在doswin下有区别,因为\r\n\n的切换。

linux内核看来,文本文件和二进制文件是一样的。

只不过文本方式通常存的都是ascii之类的文字,所有他们的字节长度有一定规范,比如A65,转为二进制01000001。那么就保存为0100000101000001 01000001就是A A。但是二进制,都入的字节不一定按照这样解析。比如,我自己的程序把这个二进制看作是用户的权限。

从这个角度看,带有BOMUTF-8的都不属于文本文件。

什么是BOM,通过在文件的最开始,保存几个无法打印的字符,来识别该文件的编码格式,就是BOM(这些字符通常在各个编码都无法打印,比如空字符)。那么这些字符就起到了其他的作用,而且,UTF-8还属于变长型编码,不能简单的按照ASCII解码。


还有个问题,使用C编程的时候,printf输出文字,默认的是ASCII,如果想输出utf-8怎么办?



第二个问题:

linux下如何识别不同文件的编码格式?

windows下生成的文件会有BOM进行辅助识别。但是linux下却没有。那linux如何识别呢?一般的识别算法都是针对普遍情况,对于特定的构造的文件可能无法识别。

比如发现一篇文章的字符编码,抽查了n次,满足UTF-8UNICODEGBK编码格式,

就继续,知道发现两个不满足。


UNICODE UTF-8
00000000 - 0000007F 0xxxxxxx
00000080 - 000007FF 110xxxxx 10xxxxxx
00000800 - 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
00010000 - 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
00200000 - 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
04000000 - 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx


比如UTF-8,第一个字节如果前三位是110,第二个前两位一定是10。不满足就不是UTF-8。可以在系统可识别的编码中使用排除法。


linux下默认的编码格式是UTF-8winGB2312。在命令行输入文字,就是UTF-8的。而且,剪切版里也是UTF-8。在页面复制的时候,将文字转码为UTF-8,如果输出到gbk的文件中需要再转码一次。


在这个过程中,为了察看win下和linuxutf-8的文件区别,使用了od命令,这个命令可以用来查看文件的16进制的形式。


od -x 文件 查看16进制

file命令查看编码格式




补充:

GB2312

ASCII 128个字符,首位为0

一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA10xFE,这样我们就可以组合出大约7000多个简体汉字了


GBK:后来还是不够用,于是干脆不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字 符集里的内容。结果扩展之后的编码方案被称为 GBK 标准


第三个问题:

空洞文件的存储问题,是像普通文件+0一样存储么?

使用o_append标志无法形成空洞。

因为这个标志意味着追加到尾端,所以偏移量总是指向文件末尾。

而且lseek也不返回错误。


U N I X 提供了一种方法使这种操作成为原子操作,其方法就是在打开文件时设置


O _ A P P E N D标志。正如前一节中所述,这就使内核每次对这种文件进行写之前,都将进程的当前位移量设置到该文件的尾端处,于是在每次写之前就不再需要调用 lseek。可以读,但是写前会原子调用lseek空洞文件


100006字节 包括100000字节的空洞 ,占用了12个存储块 ,一块是4Kdf命令)

可见空洞有一份没有保存,

如果使用cat test1,会把空洞填充的0当作实际的0数据复制,不再是空洞。

cp则不会。因为cat把数据当作0输出


注:

可能是由于ubuntu win安装的原因,

sudo tune2fs -l /dev/sda1 失败

后来df发现使用的是/dev/loop0,sudo tune2fs -l /dev/loop0


第四个问题:O_SYNCfsyncfdatasync的区别。


O_SYNC标志是文件描述符标志在 UNIX,通常write只是

将数据排入队列,而实际的I/O操作则可能在以后的某个时刻进行。数据库系统很可能需要使用

O_SYNC,这样一来,在系统崩溃情况下,它从write返回时就知道数据已确实写到了磁盘上。

普通的write加入队列直接返回。




比较O_SYNCfsyncfdatasync等的区别和效率

http://blog.csdn.net/cindy9902/article/details/5827183

http://blog.csdn.net/wangfeng2500/article/details/8288775


数据库总能用到上面的函数。




第五个问题:

多个进程写同一个文件如何管理


http://blog.chinaunix.net/uid-24585858-id-2856540.html


第六个问题:如何实现fread的缓冲功能:



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