ANSI C文件IO管理

ANSI C文件IO管理

1.1.1 文件与流的基本概念
文件:文本文件:ASCII文件
二进制文件:数据按其在内存中中的形式存储数据

缓冲文件操作:在用户空间自动为正在使用的文件开辟内存缓冲区
非缓冲文件操作:用户手动开辟;

使用缓冲机制原因:
减少CPU状态的切换,即从用户态切换到内核态;待缓冲区满后,或确实需要更新的时候在调用系统将该文件一次性写入磁盘。
带缓冲文件操作/非缓冲文件操作
缓冲区分为:全缓冲区、行缓冲区、无缓冲区

ANSI标准C库函数用流的概念实现这一特性,也就是用流对文件进行操作

1.1.2 标准流及流的主要功能
在Linux系统中,系统默认为每个进程打开三个文件,即标准输入流stdin 标准输出流stdout 标准错误输出流stderr.

输入流:键盘 某个文件 管道等
输出流 错误输出流:显示器 文件 管道

在shell应用中,重定向操作就是修改输入\输出流

1.1.3文件流指针
在应用编程层面,程序对流的的操作体现在文件流指针FILE上.
typedf struct _IO_FILE FILE
struct _IO_FILE{
int flags;
char* _IO_read_ptr; /* Current read pointer /
char
_IO_read_end; /* End of get area. /
char
_IO_read_base; /* Start of putback+get area. /
char
_IO_write_base; /* Start of put area. /
char
_IO_write_ptr; /* Current put pointer. /
char
_IO_write_end; /* End of put area. /
char
_IO_buf_base; /* Start of reserve area. /
char
_IO_buf_end; /* End of reserve area. */

};
示例:打印打开文件流指针成员信息

r/rb 以只读方式打开,读位置位于文件开始
r+/rb+ 以可读写方式打开,读写位置位于文件开始
w/wb 以只写打开,文件存在则清空,不存在则创建,写位置位于文件开头
w+ 读写,文件存在清空,写位置位于文件开头
a 只写追加文件,文件存在,则写入数据追加到文件后面,写位置始终位于文件尾部
a+ 可读写追加文件,读位置位于文件开头,写位置位于文件结尾

由打开方式不同,指针所指地址不同.
#include “stdlib.h”
#include “stdio.h”
#include “string.h”

#define ptr(CONTENT,MSG) printf(CONTENT":\t%p\n",MSG)

int main(int argc,char* argv[])
{
FILE *fp_src,*fp_des;
char buffer[10],buffer1[128];
int i;
if((fp_src=fopen(argv[1],“r+”))==NULL){
perror(“open1”);
exit(EXIT_FAILURE);
}

if((fp_des=fopen(argv[2],"a+"))==NULL){
	perror("open2");
	exit(EXIT_FAILURE);	
}
setvbuf(fp_src,buffer1,_IOLBF,128);

do{
	ptr("src_IO_read_ptr",fp_src->_IO_read_ptr);
	ptr("_IO_read_end",fp_src->_IO_read_end);
	ptr("_IO_read_base",fp_src->_IO_read_base);

	ptr("src_IO_write_ptr",fp_src->_IO_write_ptr);
	ptr("_IO_write_base",fp_src->_IO_write_base);
	ptr("_IO_write_end",fp_src->_IO_read_end);

	ptr("_IO_buf_base\t",fp_src->_IO_buf_base);
	ptr("_IO_buf_end\t",fp_src->_IO_buf_end);

	memset(buffer, '\0', 10);
	i = fread(buffer,1,10,fp_src);
	fwrite(buffer,1,i,fp_des);

	ptr("des_IO_read_ptr",fp_des->_IO_read_ptr);
	ptr("des_IO_write_ptr",fp_des->_IO_write_ptr);

}while(i==10);


fclose(fp_src);
fclose(fp_des);
return 0;

}
运行结果:
…2_linux_program$ ./ptr_struct_file test.txt test2.txt
src_IO_read_ptr: 0x7fff52acef80
_IO_read_end: 0x7fff52acef80
_IO_read_base: 0x7fff52acef80
src_IO_write_ptr: 0x7fff52acef80
_IO_write_base: 0x7fff52acef80
_IO_write_end: 0x7fff52acef80
_IO_buf_base : 0x7fff52acef80
_IO_buf_end : 0x7fff52acf000
des_IO_read_ptr: 0x215b880
des_IO_write_ptr: 0x215b886
1.1.4 缓冲区类型
标准IO提供3中类型缓冲区:全缓冲区 行缓冲区 无缓冲区

全缓冲区:默认大小BUFSIZ,由系统定义,在缓冲区满或者调用fflush才刷新,一般为普通磁盘文件的流
行缓冲区:系统默认128
无缓冲区:标准IO库不对字符进行缓存
标准输入输出设备:无交互设备时,标准输入输出流时全缓冲区的
标准错误输出设备:绝不会是全缓冲区的
1.1.5 指定缓冲区
setbuf()
setvbuf()

FILE *fp = NULL;
setbuf(fp,NULL);
setvbuf(fp, NULL, _IONBF, 0);

1.2
1.2.1 打开文件
FILE *fp;
fp = fopen("(文件路径)", “(打开方式)”);

fclose(fp);

1.2.2 读/写文件流

  1. 字符读写
    ch = fgetc(fp);
    fputc(ch, “…”);
  2. 行读写文件流
    fgets(buf, size, fp) fputs(str, fp)
  3. 块读写文件
    fread(buf, size, block, fp);
    fwrite(buf, size, block, fp);
  4. 文件流检测
    feof 判断文件是否结束
    ferror 判断流是否出现了错误

1.2.3 文件流定位
ftell(fp); //返回流当前位置距离文件开始的字节数
fseek(fp, size, _whence); //修改当前读写位置,基于第三个参数修改.
/*
#define SEEK_SET 0 //文件开始位置
_CUR 1//当前位置
_END 2//文件结束位置
*/

1.3 流的格式化输入/输出操作
1.3.1 printf/scanf 标准输入输出,即显示器 键盘
1.3.2 fprintf/fscanf
fprintf(fp, “%s”, buf);
第二个参数,输出格式
fscanf(fp, “%s”, buf);
可以
fscanf(fp, “%u %u %u”, &a, &b, &c);
1.3.3 sprintf
主要针对字符串,可以把整数转为字符串
sprintf(s, “%d”, 123);
可按照8 16进制打印
1.3.4 sscanf
以固定的字符串为输入源
1.提取字符串
sscanf(“123456”, “%s”, str);
2.去长度为4字节的字符串
sscanf(“123456”, “%4s”, srt);
3.取到指定字符为止
sscanf(“123456 abcdef”, “[^ ]”,str);

~/2_linux_program$ ./test_sscanf
test:123456
test:1234
test:123456abcdef
test:123456abcdef
bufsize:0
~/2_linux_program$ cat test_sscanf.c
#include “stdio.h”
#include “stdlib.h”
#include “error.h”
#include <string.h>

int main()
{
char testbuf[128];

sscanf("123456", "%s", testbuf);
printf("test:%s\n",testbuf);

memset(testbuf, ‘\0’, 127);

sscanf("1234 5678", "%[^5]", testbuf);
printf("test:%s\n", testbuf);

memset(testbuf, ‘\0’, 127);

sscanf("123456abcdefABCDEF", "%[1-9^a-z]", testbuf);
printf("test:%s\n", testbuf);

memset(testbuf, ‘\0’, 127);

sscanf("123456abcdefABCDEF", "%[^A-Z]", testbuf);
printf("test:%s\n",testbuf);

memset(testbuf, ‘\0’, 127);

printf("bufsize:%d\n", strlen(testbuf));
return 0;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值