文件io(缓存机制)

标准IO


概念:===》IO   I == input
O == output
  ===>输入输出


基本IO:
getchar()/putchar()   ===>单字符IO
gets()/puts()         ===>字符串io
scanf()/printf()      ===>格式化io


====》i  getchar  gets   scanf  ==>从键盘终端获取用户输入
 o  putchar  puts   printf ==>向屏幕终端输出信息
    ====》基本 io 都是基于默认的终端。


标准io不单单是终端设备,面向所有linux文件。《===一切皆为文件


标准io不在是只操作键盘和显示器,还有普通文件。
所有文件操作:
   文件打开 ===》文件读写  ===》 文件关闭


标准io操作过程中有一个默认标准设备:
1、标准输入设备:键盘终端
2、标准输出设备:显示器终端
以上两个文件默认由系统在进程启动的时候自动打开。


io分类:
1、文件io:操作系统对外提供的一组系统调用接口函数
  man 2 xxx  ===> 查看xxx文件io函数帮助


2、标准io:操作系统在文件io基础上封装的一组库函数
  man 3 xxx   ===>查看xxx标准io函数帮助






标准io的使用:===》printf("hello ");


#include <stdio.h>  /// stdio.h 标准输入输出头文件, c库头文件
/// /usr/include/stdio.h
/// <> 系统头文件路径用,可以省略。
/// "" 自定义头文件路径用 /xxx/yy/zz/xx.h
/// printf函数在stdio.h有声明


int main()          ////main 为什么int返回 ?能不能是其他?
//// gcc 编译器在linux中默认用int 表示函数返回
////int 可以换为其他类型,但必须与return一致
               ////()的参数应该是什么样的 ? == (void)
//// (int argc ,char *argv[])? 主函数传参
{
printf("hello world");   ///输出可能有错位。
while(1)
{
sleep(1);///睡眠1秒
}
return 0;
}




缓存机制:===》标准io中的函数默认存在缓存区,会缓存数据。


1、行缓存 ===》在进行io操作的时候,标准输入/输出设备默认是
  行缓存设备。输出终端和输入终端没有见到'\n'
  不会同步数据到目标设备。
  printf("asfsd"); ==>目标是标准输出设备==》会缓存
  pirntf("asdfa\n");==>'\n' 会同步信息到输出设备


  如何测试一下行缓存的大小?


2、满缓存  ==》在进行io操作的时候,每个文件都有自己的缓存区
  如果数据填充满缓存的时候会自动刷行缓存区并同步
  到目标设备。
  ====>默认的输出设备缓存区是 1024 字节;
  ====>默认的输入设备缓存区是 4096 字节;
  ====>普通文件额默认缓存区是 4096 字节;
3、不缓存 ==》区别以上两个方式,完全不存在缓存区,直接同步数据。
    ===>要验证不缓存需要如下函数:fprintf
int fprintf(FILE *stream, const char *format, ...);
==>FILE * stream  ==》文件流对象 ==》文件流指针
==>功能:将本该以格式方式输出的屏幕的数据直接输出
 到指定的文件流对象上。
===>stream 流对象有三个默认流:
    stdin: 默认的标准输入流对象  ==  键盘终端
stdout:默认的标准输出流对象  ==  显示器终端
stderr:默认的标准错误输出流对象 == 显示器终端
以上三个流对象在进程启动时候自动打开。


==》fprintf(stderr,"信息");==》信息有没有"\n"都能刷新
==》fprintf(stdout ,"xxx") 等价与 printf("xxxx");
==》stderr设备属于不缓存设备
==》stdout设备属于行缓存设备
==》stdin 设备属于行缓存设备


4、缓存区的刷新时机:
4.1 程序结束自动会刷新。
4.2 进程缓存区满自动刷新。
4.3 可以强制刷新 fflush(NULL)。
4.4 如果在输出的时候有输入操作则会自动刷新。
printf("请输入:"); scanf();
================================================================


FILE  ===> 标准文件操作对象 ===》FILE * 
      ===>文件流指针
 ====>分类: 文本流   ===》该文件内容是ASCII码构成
     二进制流 ===》该文件内容是二进制数据


文件的基本操作:io操作函数


文件的打开 ===》文件的读写 ===》文件的关闭
      fopen()          四组八个函数        fclose()


1、文件的打开:fopen
 FILE *fopen(const char *path, const char *mode);
 功能:该函数可以打开指定路径+名称的文件并返回文件流指针。
 参数:path 要打开的目标文件路径+名称
       mode 要打开的目标文件方式,有如下几种:
 "r"   只读方式打开,要求文件必须存在。
 "r+"  读写方式打开,要求文件必须存在。
 "w"   只写方式打开,如果文件没有则创建,如果有文件则清空
 "w+"  读写方式打开,如果文件没有则创建,如果有文件则清空
 "a"   只写方式打开,如果文件没有则创建,如果有文件则追加
 "a+"  读写方式打开,如果文件没有则创建,如果有文件则追加
  返回值:成功  返回一个文件流指针
 失败  NULL,而且会设置设置错误码


  fdopen()   freopen()


2、关闭文件  fclose
int fclose(FILE *stream);
功能:该函数用于关闭一个已经打开的文件流指针。
参数:stream 要关闭的文件流指针,该指针必须有效
 且不能重复关闭
返回值:成功 0
失败 -1;


3、文件IO函数,四组八个


fgetc()/fputc();   ==>单字符读写
fgets()/fputs();   ==>字符串读写
fscanf()/fprintf();==>格式化读写
fread()/fwrite();  ==>二进制读写




3.1 单字符读写
getchar()== getc(stdin) == fgetc(stdin)
键盘终端     stdin          任意文件


int fgetc(FILE *stream);
    功能:该函数可以从打开的文件流对象中获取一个字符并返回。
参数:stream 要取数据的目标流对象
返回值:成功 返回获取的文件中的一个字节
失败/文件结尾  EOF


putchar() == putc(c,stdout) == fputc(c,fp);
显示器终端     c == stdout       c == fp


int fputc(int c, FILE *stream);
功能:该函数可以将字符c写入到目标stream流对象关联的文件中。
参数:c 要写的目标字符
 stream 要写入的目标文件流对象
返回值:成功 写入的字符
失败 EOF




练习:
1、根据以上读写函数验证fopen的不同读写mode形式。


2、提示用户任意输入信息,并将用户输入的信息写入
   一个文件,当用户输入"quit" 的时候,打印输出
   用户输入数据的总长度并退出。
   要求:尽量使用fgetc/fputc完成。


3、使用fputc验证普通文件的缓存区是4096字节大小。




4、使用主函数传参方式,传入任意文件并使用fgetc/fputc的
   的方式将文件内容打印到屏幕终端。
    ./a.out  xxx.h ===>将xxx.h的文件内容输出到屏幕。




作业:
使用fgetc和fputc方式完成任意指定文件的数据统计
要输出文件的单词个数  行数  总大小字节
比如:
./a.out  xxx.h


单词=13   行 = 100  总大小= 352字节

















猜你喜欢

转载自blog.csdn.net/flying_man_/article/details/79059806
今日推荐