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

来源:互联网 发布:微信被加软件 编辑:程序博客网 时间:2024/06/17 02:04

接上篇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送入硬盘中,缓冲区刷新,第一个字符成了bfclose(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
原创粉丝点击