复撸C系列(4)-文件基础IO(续)

接上篇FILE的相关函数,继续看。

1.setbuf

void setbuf ( FILE * stream, char * buffer );

stream 文件流指针

buffer 将此buffer设置为stream的缓冲区,如果是NULL的话,表示不需要缓冲区,一有内容就写入硬盘

 

注意:在任何读写操作(fread, fwrite)之前就要设置要缓冲

1.1示例:

#include "stdafx.h"
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	char newbuffer[1000] = {'\0'};
	FILE *fileForNewBuf = fopen("test.txt","w"); //示例就不检查fileForNewBuf是否为空了
	setbuf(fileForNewBuf, newbuffer);
	const char *str = "some test srings in buffer";
	fwrite(str, 1, strlen(str), fileForNewBuf); // 缓冲区没满,这里没写入硬盘
	    fclose(fileForNewBuf);  //这里面fflush了,写入硬盘
	return 0;
}

1.2示例:

测试无缓冲情况
#include "stdafx.h"
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	FILE *noBufferFile = fopen("test.txt","w");
	setbuf(noBufferFile, NULL); //无缓冲,有内容即马上写入硬盘
	fwrite("a", 1, 1, noBufferFile);//这里已经写入硬盘
	fclose(noBufferFile);
	return 0;
}

函数的描述:


这里可以看到有一个最小缓冲长度,进去看可以发现是

(我的机子上,VS2012)

也就是说即便我们设置了char buf[10] 这样短的缓冲区,还是会被强制改成大小是512的,大于512的话就是实际设置的长度。这里面还说了stdin和stdout一般都是全缓冲或者行缓冲或者无缓冲,以来于系统的实现,不过一般都是行缓冲。stderr一般是行缓冲或者无缓冲。

 “全缓冲”: 设置的缓冲区满了才往硬盘写。

 “行缓冲”: 遇到换行(或缓冲区满)才往硬盘写。

 “无缓冲”: 只要有字马上写入硬盘。

关于如何设置缓冲模式,看下一个函数。

 

2.setvbuf

int setvbuf ( FILE * stream, char * buffer, int mode, size_t size );

       stream文件流指针

       buffer缓冲区

       mode缓冲模式

三种缓冲分别对应了之前说的情况

       size  缓冲区大小,如果buffer是null,则由系统动态申请

       返回值 : 成功返回0,不成功非0

2.1 全缓冲示例:

#include "stdafx.h"
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	char fullBuf[566] = {};
	FILE *file = fopen("test.txt","w");
	setvbuf(file,fullBuf, _IOFBF, 566); //写满566个字符才送入硬盘
	for (int i = 0; i < 566; ++i)
	{
		fwrite("a", 1, 1, file);
	}
	fwrite("b", 1, 1, file); //这一句把566个a送入硬盘中,缓冲区刷新,第一个字符成了b
	fclose(file);
	return 0;
}

2.2 行缓冲示例:

#include "stdafx.h"
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	char lineBuffer[1024] = {};
	FILE *file = fopen("test.txt","w");
	int ret = setvbuf(file, lineBuffer, _IOLBF, 1024);
	const char *str = "test line buffer";
	fwrite(str, 1, strlen(str), file); //这里还没写入硬盘
	fwrite("\n", 1, 1, file); //这里写入 , 但我在win7+vs2012上没有写进去,查了半天在MSDN才找到解释,起初还以为自己写错了,解释在下方截图
	fclose(file);
	return 0;
}



WIN32下面没有行缓冲一说,只有全缓冲,好操蛋,害我找半天原因。

 

2.3无缓冲示例:

#include "stdafx.h"
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	char lineBuffer[1024] = {};
	FILE *file = fopen("test.txt","w");
	int ret = setvbuf(file, lineBuffer, _IONBF, 1024);
	const char *str = "test no buffer";
	fwrite("a", 1, 1, file); //这里写一个字都会输出到硬盘去
	fwrite(str, 1, strlen(str), file);	 //这句话也马上输出到硬盘
fclose(file);
	return 0;
}

到这里,基本的文件输入输出也差不多了,一般带个’f’的(fprintf,fputs,fgets….)就表示对文件进行操作,省略了’f’的(printf, puts,….)一般是绑定在stdout,stdin,stderr这三个系统初始就有的流上面,带个’v’的(vprintf,vscanf,….)表示接受一个va_list 的参数(我没怎么用过)。

 

小结:

文件的本质上是一块内存(缓冲区)加一个管理对象(FILE结构体内的各个成员),stdout,stdin,stderr本质上也是文件。我们可以改变它们的缓冲方式,缓冲区大小,可以格式化输出。但是究其根本也只是个库,和C语言本身并无关系,在不同的平台下有各自不同的实现。就像_IOLBF在WIN7上根本就是不提供的,还害我查半天的错,囧。文件再深入本质一点就是内存地址,也就是说我们和底层硬件进行沟通,其实都是通过地址以及偏移来操作的。其实我觉得自己还是需要去学一点汇编的知识,更好地理解内存。

 

好啦,下一篇开始指针。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值