一直以来对c的IO函数一知半解,今天终于仔细研究了一下有些醍醐灌顶的感觉。
首先是对文件的理解。linux下,一切皆为文件,liunx就是一个大文件系统。
我们常见的文件一般是,文本文件和二进制文件。
文本文件主要是记录一些可读字符,这些字符是以字节为单位组织起来,可以是ascii码 utf8,iso gbk等编码形式。
主要可以是文件,源码文件等等。
二进制文件 则不是一些可读的文件,如系统中可执行文件,库文件,目标文件等。每个字节中的二进制位可能代表,地址,数据,指令。等等
设备文件,每个设备也被linux 抽象成一个文件,这些设备文件没有size这样的属性,因为它连接外部设备,将数据输出到设备外,或是度入到内存中。
Linux 中的设备有2种类型:字符设备(无缓冲且只能顺序存取)、块设备(有缓冲且可以随机存取)。每个字符设备和块设备都必须有主、次设备号,主设备号相同的设备是同类设备(使用同一个驱动程序)。这些设备中,有些设备是对实际存在的物理硬件的抽象,而有些设备则是内核自身提供的功能(不依赖于特定的物理硬件,又称为"虚拟设备")。每个设备在 /dev 目录下都有一个对应的文件(节点)。可以通过 cat /proc/devices 命令查看当前已经加载的设备驱动程序的主设备号。内核能够识别的所有设备都记录在原码树下的 Documentation/devices.txt 文件中。在 /dev 目录下除了字符设备和块设备节点之外还通常还会存在:FIFO管道、Socket、软/硬连接、目录。这些东西没有主/次设备号。
详情参考 http://lamp.linux.gov.cn/Linux/device_files.html
因为文件基本构成都是一样所以可以以读字节方式读取整个文件。
linux 有几个IO 的系统调用 都是无缓冲的,他们适用任何IO操作 open close read write lseek
频繁访问系统内核,效率低
对其封装成带有缓冲的文件操作IO
FILE 文件结构体 包括一个文件描述符,和文件缓冲区地址,以及一个指针
FILE * fd = fopen (const * str,const * op)//错误返回 NULL
r, w ,a , r+, w+ ,a+
fclose(fd); //成功返回0 错误返回EOF,并设置 errno
stdin stdout stderr 分别表示, 标准输入,标准输出,和标准错误输出,是与用户交互操作的一些
程序出现错误的时候 会设置errno
输出errno 同时 输出对应的错误说明 可以使用 perror(自定义错误日) 函数 和 strerror(errno)
fgetchar 与 fputchar (getchar 与putchar 是 标准输入输出的版本)
fgetchar 是行缓冲函数
每次读入一个字符到缓冲区,当遇到换行时,清空缓冲区。
当读到文件位的时候 返回EOF -1 0xFFFFFFFF
返回值是 int 要区分 EOF 和 0xFF ,如果不是EOF 转化为unsigned char 返回
getchar有一个int型的返回值.当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符也放在缓冲区中).当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符.getchar函数的返回值是用户输入的第一个字符的ASCII码,如出错返回-1,且将用户输入的字符回显到屏幕.如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取.也就是说,后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键.
getch与getchar基本功能相同,差别是getch直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch就立刻返回, getch返回值是用户输入的ASCII码,出错返回-1.输入的字符不会回显在屏幕上.getch函数常用于程序调试中,在调试时,在关键位置显示有关的结果以待查看,然后用getch函数暂停程序运行,当按任意键后程序继续运行.
文件结束可以使用ctrl + d 也可以使用linux heredoc 《end 《end
有三个对文件位置修改的文件
rewind 对文件指针回到文件头
fseek(File * fd, int offset, int wherence)// offset 可正可负 如果超出了文件范围,在读写则添零
ftell(File * fd)
可以对文件分块,多线程传输
SEEK_SET
从文件开头移动offset个字节
SEEK_CUR
从当前位置移动offset个字节
SEEK_END
从文件末尾移动offset个字节
fgets (char * buf, int size, FILE *fd) //从fd 读取长度为size-1长的的字符串 并在读取的数据后加入/0作为字符串结束符
如果遇到换行,则返回
如果所读行的大小大于 缓冲区大小则截断 字符串
对于fgets来说,'/n'是一个特别的字符,而'/0'并无任何特别之处,如果读到'/0'就当作普通字符读入。如果文件中存在'/0'字符(或者说0x00字节),调用fgets之后就无法判断缓冲区中的'/0'究竟是从文件读上来的字符还是由fgets自动添加的结束符,所以fgets只适合读文本文件而不适合读二进制文件,并且文本文件中的所有字符都应该是可见字符,不能有'/0'。
如果文件结束则返回NULL
fread 和fwrite 对记录的读取, 可以读取一个结构体或是一个数组
太晚了先写这么多