我刚刚接受了一些在Linux下开发的文件阅读器的旧代码,并尝试在使用MSVC ++ 7.1编译的Windows项目中使用相同的代码。编译时代码没有任何问题,但根据Windows上的文件阅读器,该文件似乎是空的。
我将问题跟踪到ifstream.readsome(),它没有从文件中读取任何内容,而没有在流上设置任何错误标记。下面提供的代码在Linux和Windows上编译,但Linux可以按预期工作。
代码打开一个文件,用read()
一次读取文件的前512个字节,用readsome()
读取一次。两个结果都存储在两个向量中,这些向量在程序结束时进行比较。预期的结果是两个向量相等。
Windows XP上程序的结果输出发布在源代码下方。
如果有任何想法或猜测此代码中可能出现的问题,我很乐意听到它们。
#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>
int main()
{
const size_t BUFFER_SIZE(512);
std::ifstream in("some.file", std::ios::in | std::ios::binary);
if(in.is_open())
{
std::vector<char> buf1(BUFFER_SIZE);
std::vector<char> buf2(BUFFER_SIZE);
assert(buf1 == buf2);
if(in.seekg(0, std::ios_base::beg).good())
{
//read BUFFER_SIZE bytes from the file using read()
if(in.read(&buf1[0], buf1.size()).eof())
{
std::cerr << "read() only read " << in.gcount() << " bytes." << std::endl;
}
else
{
std::cout << "read() could read all 512 bytes as expected." << std::endl;
}
if(!in.good())
{
std::cerr << "read() set an error flag in ifstream." << std::endl;
}
}
else
{
std::cerr << "Can not test read()." << std::endl;
}
if(in.seekg(0, std::ios_base::beg).good())
{
//read BUFFER_SIZE bytes from the file using readsome()
std::streamsize bytesRead = in.readsome(&buf2[0], buf2.size());
if(bytesRead != BUFFER_SIZE)
{
std::cerr << "readsome() only read " << bytesRead << " bytes." << std::endl;
}
else
{
std::cout << "readsome() could read all 512 bytes as expected." << std::endl;
}
if(!in.good())
{
std::cerr << "readsome() set an error flag in ifstream." << std::endl;
}
}
else
{
std::cerr << "Can not test readsome()." << std::endl;
}
//should read from the same file, so expect the same content
assert(buf1 == buf2);
}
return 0;
}
read() could read all 512 bytes as expected.
readsome() only read 0 bytes.
Assertion failed: buf1 == buf2, file [...], line 60
答案 0 :(得分:3)
readsome()
用于进行非阻塞读取,正如这意味着实现定义(或由您的自定义streambuf成员showmanyc()
定义),行为可能会有所不同。对我来说两者都是正确的。
答案 1 :(得分:0)
断言“断言(buf1 == buf2);”在调试模式下编译时失败,因为buf1和buf2只被告知要保留内存(只是分配内存,而不是初始化它),而operator ==实际上比较了两个具有未定义值的缓冲区。
对于“read(...)”和“readsome(...)”,我的建议是坚持使用“read(...)”来处理大多数情况。