使用ifstream读取文件,windows fread注意事项

今天要使科大讯飞的语音识别SDK,根据需要要打开一个语音文件;同事之前是在linux系统使用的,当代码放到windows中用VS编辑

修改后,发现不能将wav文件正确读取出来,经过一下午的原因,发现是因为linux都是二进制读写,而windows要区分文本读写还是二进制

读写,代码如下

	FILE * fp = ::fopen(argv[1], "rb");//就是这里linux下是r方式打开,windows则必须是rb才能保证完整读取,因为r是文本读取会忽略空白和换行,并且在遇到0x1a
	::fseek(fp, 0, SEEK_END);          //会直接返回,不会再向后面读取
	int fileLength = ftell(fp);
	::fseek(fp, 0, SEEK_SET);
	std::shared_ptr<char> buf(new char[fileLength], [=](const char* p) ->void {delete p; });
	int readItems{ 0 };
	while (readItems != fileLength) //不要使用feof()函数,参考这篇博客
	{
		readItems += ::fread(buf.get() + readItems, 1, fileLength,fp); //返回实际读取的字节数
		std::cout << "has read " << readItems * 100 << " bytes. " << readItems << " Items fileSize " << fileLength << std::endl;
	}
	::fclose(fp);

后面我想了想既然在用c++那当然是用流来读取更好,于是写成了下面这样

	std::ifstream inFile(argv[1],std::ifstream::binary);//二进制读取
	inFile.seekg(0, std::ifstream::end);
	int fileLength = inFile.tellg();
	inFile.seekg(0, std::ifstream::beg);
	std::cout << "file size " << fileLength << std::endl;

	std::shared_ptr<char> p(new char[fileLength], [=](const char *ptr) {delete ptr; });

	int readCount{ 0 };
	while (inFile.read(p.get() + readCount,fileLength)) //用ifstream的read方法返回值判断,不要用ifstream的eof方法,原因同上。第二个参数不能
	{//fileLength-readCount这样会造成死循环,读完文件后,每次读0字节,read返回的还是读取成功。
		readCount += inFile.gcount(); //实际读取的大小在gcount()方法返回值中
		std::cout << "has read " << inFile.gcount() << " bytes" << std::endl;
	}
经测试以上方法可行,最后个人感觉windows上面不适合好做文件检测末尾,有点反常理,我觉得windows这样做应该是为了文本文件与数据类型之间的读写以及
采用>>和<<来读写的方便,因为这样用就可以方便的自动检测文件末尾。所以最后我直接读了整个文件,因为这里读取的长度是任意的。

	std::ifstream inFile(argv[1],std::ifstream::binary);
	inFile.seekg(0, std::ifstream::end);
	int fileLength = inFile.tellg();
	inFile.seekg(0, std::ifstream::beg);
	std::cout << "file size " << fileLength << std::endl;

	std::shared_ptr<char> p(new char[fileLength], [=](const char *ptr) {delete ptr; });

	inFile.read(p.get(), fileLength);
	std::cout << "has read " << inFile.gcount() << " bytes" << std::endl;
	inFile.close();
最后还有关于istreambuf_ilterator与istream_ilterator的区别,主要是前一个会原模原样的在文件流中读取,后一个会忽略掉空格和换行。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值