关于I/O操作的一点整理

5 篇文章 0 订阅

今天遇到一个程序bug,A向B发送完整的一段数据,B却总是不能获取到结尾部分的内容。后来才发现在进行“write”操作(ngx.print)后还需要调用flush操作(ngx.flush)才能将数据写出。对数据IO,缓存的知识又忘光光了,这里整理一下:

对于文件描述符的操作比较简单,不同的操作系统都封装了比较好用的fstream库函数。基于流的操作最终会调用read和write函数进行IO操作,操作系统为了提升程序的运行效率,尽可能减少write和read操作的调用次数,通常会提供缓存。

缓存的类型分全缓存(读入/写出内存字节数等于缓冲区大小或者文件已经到结尾才进行IO操作,写磁盘一般是属于这种类型);行缓存(直到遇见“\n”才会进行IO操作,标准输入stdin和标准输出stdout属于这种类型);无缓存(立即进行IO,如stderr),我们可以在程序中设定流的缓存方式。

#include<stdio.h>
#define SIZE 1024
void check_buf_type(){

	if(stdin->_flags & _IO_UNBUFFERED) {
		printf("stdin unbuffered");
	}
	else if(stdin->_flags & _IO_LINE_BUF) {
		printf("stdin line-buffered");
	}
	else{
		printf("stdin fully-buffered");
	}
	printf("\n");
}

int main()
{
	check_buf_type();
	char buf[SIZE];
	if(setvbuf(stdin, buf, _IONBF, SIZE) != 0) {
		printf("error!");
		return -1;
	}
	check_buf_type();
	if(setvbuf(stdin, buf, _IOLBF, SIZE) != 0) {
		printf("error!");
		return -1;
	}
	check_buf_type();
	return 0;
}
关于缓存内容,我们在进行文件IO后,不一定保证它已经写入到磁盘或者网络套接口,存在缓存的情况下可能需要调用fflush函数强制写入磁盘文件或者fpurge清空缓存内容。


今天还遇到另外一个问题,Lua文件操作的打开模式,如下面的例子,我原本想先在文件头部写入字符串,然后再在偏移100位置处再写入字符串,可是由于中间关闭了一次,又打开后前面一次写入的内容就被清除了。示例代码如下:

local out = io.open("test","wb")
out:seek("set")                 -- 将游标设置在文件头
out:write("Hello World")
out:close()

out = io.open("test","wb")
out:seek("set",100)
out:write("Hello World")
out:close()
其实这也是我文件操作方式不对导致的,“w”方式打开会将文件长度置零,改成下面的方式就可以了,“r+”表示读写方式
local out = io.open("test","wb")
out:seek("set")                 -- 将游标设置在文件头
out:write("Hello World")
out:close()

out = io.open("test","rb+")
out:seek("set",100)
out:write("Hello World")
out:close()
可是需要注意的是“r+”模式不能打开一个不存在的文件,不然out会被设置为nil,所以如果要以读写方式打开,需要事先判断改文件是否存在。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值