IO 的基础知识 IO的目的就是要学会对文件的输入与输出
1.什么是文件?
文件:一组相关数据的有序合集
文件名:这个数据集合的名称
在我们linux中有什么类型文件
常规文件:-
ASCII码文件
二进制的文件
目录字符设备:c
块设备:b
有名管道:p -- 在多进程线程中会用到
套接口:s --在网络编程中用到
符号链接:l --软硬连接
系统调用
用户空间进程访问内核的接口
把用户从底层的硬件编程中解放出来
极大的提高了系统的安全性
使用户程序具有可移植性
是操作系统的一部分
库函数
库函数为了实现某个功能而封装起来的API集合
提供统一的编程接口,更加便于应用程序的移植
是语言或者应用程序的一部分
文件描述符
顺序分配的非负整数
内核用以标识一个特定进程正在访问的文件
其他资源(socket,pipe等)的访问标识
标准输入、标准输出和标准出错
由shell默认打开,分别是0/1/2
不用缓存的I/O ---文件IO
通过文件描述符进行访问
open()/read()/write()/lseek()/close()
标准I/O
通过FILE*进行访问
printf()/fprintf()/fopen()/fread()/fwrite()/fseek()/fclose()
全局错误码errno
在errno.h中定义,全局可见
错误值定义为"EXXX"形式,如EACCESS
sudo vim /usr/include/asm-generic/errno-base.h
sudo vim /usr/include/asm-generic/errno.h
处理规则
如果没有出错,则errno值不会被一个例程清除,即只有出错时,才需要检查errno值
任何函数都不会将errno值设置为0,errno.h中定义了所有常数都不为0
错误信息输出
strerror() --映射errno对应的错误信息
perror() --输出用户信息及errno对应的错误信息
标准IO
1.标准IO的概念
不仅在UNIX系统,在很多操作系统上都实现了标准I/O库 ---很多系统都可以使用
标准I/O库由ANSI C标准说明 ---由c库提供
标准I/O库处理很多细节,如缓存分配、以优化长度执行I/O,这样使用户不必关系如何选择合适的块长度 ---比较智能
标准I/O在系统调用函数的基础上构造的,它便于用户使用 ---在文件I/O的基础上制作
标准I/O库以及头文件stdio.h为底层I/O系统调用提供了一个通用的接口
2.文件指针 ----标准I/O的核心
FILE指针:每个被使用的文件都在内存中开辟了一个区域,用来存放文件的有关信息,这些信息是保存在一个结构体类型的变量中,该结构体类型是由系统定义的,取名为FILE。
标准I/O库的所有操作都是围绕流(stream)来进行的,在标准I/O中,流用FILE *来描述
标准I/O库是由Dennis Ritchie 在1975年左右编写的
3.流(stream)
所有的I/O操作仅是数据简单的从程序移进或者移出,这种字节流,就称为流
分类:文本流/二进制流。
文本流:在流中处理的数据是以字符出现。在文本流中,'\n'被转换成回车符CR和换行符LF的ASCII码0DH和0AH。而当输出时,0DH和0AH被转换为'\n'
数字2001在文本流中的表示方法为'2' '0' '0' '1' ASCII: 50 48 48 49
二进制流:流中处理的是二进制序列。若流中有字符,则用一个字节的二进制ASCII码表示;若是数字,则用对应的二进制流表示。对'\n'不进行变换
数字2001在二进制流中的表示方法为 00000111 11010001
ubuntu和windows的二进制有所不同-->两者的二进制流不能通用
缓冲文件系统(高级磁盘IO)---标准IO
目的:尽量减少使用read/write的调用
系统自动的在内存中为每一个正在使用的文件开辟一个缓冲区,从内存向磁盘输出数据必须先送到内存缓冲区,装满缓冲区在一起送到磁盘中去。从磁盘中读数据,则一次从磁盘文件将一批数据读入到内存缓冲区中,然后再从缓冲区逐个的将数据送到程序的数据区。
分类:全缓存,行缓存,不缓存
全缓冲 --- 常规文件
缓冲刷新条件:1>缓冲区满了 2>文件被关闭:fclose/close 3>程序正常结束 4>强制刷新:fflush函数
行缓冲 ----- 输入/输出
1>缓冲区满了 2>文件被关闭:fclose/close 3>程序正常结束 4>强制刷新:fflush函数 5>在缓冲区遇到'\n'
不缓冲 --- 错误信息
不缓冲,没有刷新条件
非缓冲文件系统 (低级磁盘IO)--->文件IO
定义:依靠于操作系统,通过操作系统的功能对文件进行读写,是系统级的输入输出。
0 1 2 --->文件描述符下标
stdin stdout stderr--->流名
非格式化IO:无法自定义输入/输出格式的IO
1>对文件的操作: ---》利用函数从文件中读取数据,并写入到另一个文件中
1.1>打开文件
fopen
#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
功能:
标准IO的打开文件
参数:
pathname:带路径的文件名
mode:------*打开文件的权限
代号 权限 文件情况要求 模式
r 只读 文件必须存在
r+ 可读可写 文件必须存在
w 只写 文件不存在则创建 清空模式
w+ 可读可写 文件不存在则创建 清空模式
a 只写 文件不存在则创建 追加模式
a+ 可读可写 文件不存在则创建 追加模式
返回值:
成功返回:文件指针-->流
失败返回:NULL,并返回错误码
1.2>操作文件
一次操作一个字节
读: fgetc/getc/getchar
一次一行字节IO:
读:fgets/gets
写:fputs/puts
一次操作一块字节
读:fread
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
写:fwrite
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
1.3>关闭文件
fclose
#include <stdio.h>
int fclose(FILE *stream);
功能:
根据流关闭文件
参数:
stream:要关闭的流
返回值:
成功返回0
失败返回EOF