计算机系统中文件占有非常重要的地位,所有的程序、文档、数据、信件、表格、图片等等种类繁多的信息,都是用文件来保存的。
c语言将文件看成是连续的字节序列——字节流。
换句话说,在操作系统内部,unix like 系统仅有一种文件结构,文本与二进制实现是相同的。
因此使用fopen , ”r ” ” rb ”, “w” “wb ”,是一样的。
而给人看的部分,分成了文本视觉与二进制视觉。
ms-dos系统以其后代windows,就区分了文本与二进制文件,不光视觉不同,内部实现也不同。
低级i/o是操作系统提供的基本i/o服务,c语言提供了标准高级i/o.
c程序自动打开3个文件,这3个文件被称为 stdout,stdin,stderr。
前面学习的所有printf,puts,putchar,scanf,gets,getchar本质上都是文件i/o,只不过恰好默认了这3个标准文件。
printf 的上级是 fprintf。
scanf的上级是 fscanf。
puts的上级是 fputs。
gets的上级是fgets。
putchar的上级是 putc。
getchar的上级是 getc。
既可以只用上级命令完成所有的i/o读写工作,也可以混用。
打开文件: fopen,注意权限与检查打开是否成功,打开失败返回NULL。
关闭文件: fclose,注意检查是否关闭成功, 关闭失败返回EOF
终止退出程序: exit,关闭所有打开文件并终止程序。包含在stdlib.h,正常终止参数0,非正常参数非0,为了可移植exit(EXIT_SUCCESS), exit(EXIT_FALURE)。
随机存取:fseek和ftell。 文件的起始点模式
模式 | 偏移量的起始点 |
SEEK_SET | 文件开始 |
SEEK_CUR | 当前位置 |
SEEK_END | 文件结尾 |
fseek和ftell的潜在问题有两点: 1. 可移植性 2. 偏移量用long类型表示,随着存储设备容量的增大,更大的文件也有可能。
针对第二点,ANSI C引入了新的定位函数 fgetpos和fsetpos。
相对于文本模式,随机存取更适合在二进制模式下进行。
二进制 i/o相关要点。
既然一切数据都用文件保存,而文件无论是在内存中还是在磁盘上 ,都只能是二进制方式存在。
那还分什么二进制文件与文本文件呢?
在第三章数据与c中的已经说过——本质在于数据怎么存进去,怎么取出来。
对于人来说,12345是一个数字,并没有变化。
如果用文本方式存取,无论在内存中还是磁盘上,二进制数据见图。
如果用二进制方式存取,同样无论在内存中还是磁盘上,二进制数据都为 00110000 00111001。
所以这种转换可以随时发生,非常灵活。
比如内存中是文本形式二进制,写成文件后既可以是文本形式,也可以转换为纯二进制。
同理,内存中是纯二进制,写成文件后既可以是纯二进制,也可以转换为文本形式。
内存到文件可以灵活转换,再反过来文件到内存一样可以灵活转换。
事实上,二进制模式与文本模式最大的差别在于“数字”。
《c primer plus》书中原文:“术语‘文本’和‘二进制’可能会造成混淆。这些都是互相关联的,可以用二进制模式打开文本文件,可以将文本文件存储在二进制格式文件中。不过通常情况下,还是使用二进制模式将二进制数据存储到二进制格式文件中;使用文本模式将文本数据存储到文本格式文件中。”
fwrite与fread处理二进制格式文件。
feof判断文件结尾,ferror判断文件是否发生读写错误,一样可以用在文本文件。
以二进制模式打开一个文件时,可以逐字节的读取它们,当然对于unix和linux,这两种模式相同。