我以最常见的方式读取QFile
,唯一的不同是由于我的程序体系结构,我在读取循环内的文件上初始化了QTextStream
。
令我惊讶的是,这导致QFile
错误地指出了文件位置,并且由于QTextStream
这样的结果而导致只读取一行或根据文件而看似随机的行号。
QTextStream
为什么会以这种方式表现?我在文档中找不到有关此类问题的任何参考。有什么我想念的吗?
代码示例
这是我正在使用的错误代码(从体系结构中删除并简化了)
QFile file;
QString line;
int interationCount = 0;
file.setFileName(fileName);
if(file.open(QIODevice::ReadOnly | QIODevice::Text))
{
while(true)
{
QTextStream stream(&file);
if(stream.readLineInto(&line) == false)
break; //Or return
std::count << "Line "<< interationCount << ": " << line << "\n";
interationCount++;
}
}
输入和输出
给出一个文件,其编号从1到35排成一行,格式如下:
1
2
3
...
35
该算法仅读取一行输出,而预期读取所有行。
输出:
Line 0: 1
预期输出:
Line 0: 1
Line 1: 2
Line 2: 3
...
Line 34: 35
答案 0 :(得分:0)
{@ {1}}的重复构造是由于@MatteoItalia回答的原因导致此错误。
固定代码如下:
QTextStream
并产生预期的输出:
QFile file;
QString line;
int interationCount = 0;
file.setFileName(fileName);
if(file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream stream(&file);
while(stream.readLineInto(&line))
{
std::count << "Line "<< interationCount << ": " << line << "\n";
interationCount++;
}
}
其他信息
此错误似乎很明显。诅咒在循环内重复构造对象是一个坏习惯(从性能角度考虑,因为这样的错误),但是在某些体系结构中,这可能并不那么明显。
请考虑以下架构:
名为Line 0: 1
Line 1: 2
Line 2: 3
...
Line 34: 35
的父类具有虚函数,用于读取必须重载的文件的单行,可以使用FileFormat_Parrent
来实现。
QTextStream
然后在使用这些类时,将根据文件类型以适当的子类型创建class FileFormat_Parrent
{
public:
QFile File;
void* Buffer
virtual bool ReadSingle() = 0;
virtual bool WriteSingle() = 0;
};
class FileFormat_Txt : public FileFormat_Parrent
{
virtual bool ReadSingle() {/*Possibly using QTextStream to do so*/}
virtual bool WriteSingle() {...}
};
class FileFormat_BinArray : public FileFormat_Parrent
{
...
};
类。
然后,将在循环FileFormat
和ReadSingle()
之间循环使用这些创建的FileFormat,直到它们之一返回false。
这将导致发生错误代码,因为WriteSingle()
是在循环内重复构造的。
答案 1 :(得分:0)
QTextStream
不会从基础的QIODevice
字节中读取数据,而是具有内部解码的缓冲区,用于避免支付重复的虚拟调用的费用并进行编码更大的转化。
这意味着,一旦您在QIODevice
上开始使用它,它从其中读取的内容可能比从QTextStream
中读取的内容更多;这实际上是in the documentation的解释:
由于文本流使用缓冲区,因此不应使用超类的实现从流中读取数据。例如,如果您有一个
QFile
并直接使用QFile::readLine()
而不是使用流来读取它,则文本流的内部位置将与文件位置不同步。
通过连续读取和销毁QTextStream
,您总是会根据读取的缓冲区大小从文件中获取数据,然后丢弃所有未从文本流中读取的内容。