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

来源:互联网 发布:李佩谕新闻大数据 编辑:程序博客网 时间:2024/05/17 23:33

今天要使科大讯飞的语音识别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的区别,主要是前一个会原模原样的在文件流中读取,后一个会忽略掉空格和换行。