标准IO的返回值判断
feof:判断文件流指针是否到达结尾。
feof(src) //如果文件流指针到达末尾,函数返回值为真
ferror:判断文件流指针是否出错。搭配clearerr使用可以跳过报错的地方,读取后面的数据
ferror(src) //如果文件流指针出错,则函数返回值为真
clearerr(src) //跳过错误的空间
标准IO的文件定位:
fseek
//函数原型
int feek(FILE * stream,long offset,int whence);
//参数:
//stream 要移动文件指针的目标文件流对象 注意:不支持设备文件,一般用于普通文件。
//offset 需要偏移的大小
//whence 从何处开始偏移 主要有以下的宏:
//SEEK_SET 文件开头
//SEEK_CUR 当前位置
//SEEK_END 文件结尾
ftell
//函数原型
long ftell(FILE *stream);
//参数stream 文件流
//获取当前文件流指针的具体位置,一般以文件开头到当前指针的字节数为返回值
rewind
//将文件流指针指向开头
void rewind(FILE * stream);
//可用fseek替代
fseek(fp,0,SEEK_SET);
缓冲区
行缓冲,大小为1k(1024个字节),主要用于人机交互
刷新条件:
1.遇到\n
2.缓冲区满刷新
3.程序结束
4.fflush刷新至屏幕上 fflush(stdout);
//补充,系统默认打开的文件流
stdin //标准输入 数据从终端接收 搭配读取函数达到scanf的效果
stdout //标准输出 数据输出到终端上 搭配写入函数达到printf的效果
stderr //标准错误
全缓冲,大小为4k,主要用于文件的写操作
刷新条件:
1.缓冲区满
2.程序结束刷新
3.fflush来刷新 fflush(fp);
无缓冲,大小为0,主要用于出错处理信息的输出 stderr
不对数据缓存直接刷新
//程序报错写法
fprintf(stderr,"fopen error %s",filename);
流的分类
文本流
在文本流中流动的数据是以字符的形式 流动
二进制流
在二进制流中的数据是以二进制的形式流动的
文件IO
操作系统为了方便用户使用系统功能而对外提供的一组函数 。称之为系统调用,其中有一个文件IO,一般都是对设备文件操作,当然也可以对普通文件进行操作。
一个基于Linux内核的没有缓存的IO机制
特性:
1.没有缓冲区
2.操作对象不再是流,而是文件描述符 int
3.文件描述符是一个很小的非负的整数(0-1023),内核每打开一个文件,就会获得一个文件描述符。
4.每个程序在启动的时候操作系统默认会认为其打开三个描述符。
//三个描述符与流对象的匹配
//描述符 流对象
//0 STDIN_FILENO stdin
//1 STDOUT_FILENO stdout
//2 STDERR_FILENO stderr
相关函数
open
int open(const char *pathname, int flags); //函数原型
//参数:
//pathname 表示你想打开的文件的路径,是一个字符串
//flags 表示你想以什么模式打开该文件,系统提供了一些宏供你选择
//常用的宏有 //O_RDONLY 只读
//O_WRONLY 只写
//O_RDWR 读写
//O_CREAT 创建 //使用该宏时,参数要加上权限
//O_TRUNC 打开时清除文件中原有的数据
//O_APPEND 打开时在文件最后的位置追加
//返回值 如果打开成功,返回一个文件描述符(int类型),失败则返回-1
使用实例:
read
ssize_t read(int fd, void *buf, size_t count); //函数原型
//参数
//fd 文件描述符
//buf 表示你要读到哪个地方,是一个地址
//count 表示你想要读多大的空间的内容
//返回值
//成功时返回实际读到的字节数,如果等于0,表示文件已经读到末尾,失败则返回-1;
使用实例:
write
ssize_t write(int fd, const void *buf, size_t count); //函数原型
//参数
//fd 文件描述符
//buf 表示你要写进文件的内容存放的地址
//count 表示你期望写入的大小 此时填写大小要慎重,需要是内容的有效长度
//返回值
//成功时会返回实际写入文件的字节数,失败则返回-1
使用实例:
重点实例:用read和write完成对任意文件的复制
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, const char *argv[])
{
if (argc < 3)
{
fprintf(stderr,"input 2 pathname\n");
return -1;
}
int fd_src = open(argv[1],O_RDONLY); //源文件只读方式打开
int fd_dest = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666); //目标文件只写方式打开,文件不存在时创建,原有的内容也清除
//0666是该文件的权限
if (fd_src == -1 || fd_dest == -1) //任一文件描述符为-1,则打印错误信息
{
fprintf(stderr,"open error\n");
return -1;
}
char buf[1024] = {0}; //在内存上开辟一块空间用来存放读写的内容,初始化为0
while (1)
{
int ret = read(fd_src,buf,sizeof(buf)); //将源文件的内容读到buf中,且接收实际读到的字节数
if (ret == 0) //如果读到的字节数为0,表示已读到文件末尾,退出循环
{
break;
}
write(fd_dest,buf,ret); //将buf中的内容写入目标文件,此时写入的长度是实际读到了的长度
}
close(fd_src); //关闭两个文件
close(fd_dest);
return 0;
}
lseek
off_t lseek(int fd, off_t offset, int whence); //函数原型
//参数
//fd 文件描述符
//offset 偏移量
//whence 表示从何处开始偏移 系统提供的宏和fseek的一样
//返回值
//返回文件开头到当前位置的大小 相当于ftell