【问题标题】:Peek on QTextStream窥视 QTextStream
【发布时间】:2014-02-19 12:52:53
【问题描述】:

我想查看读取 QFile 的 QTextStream 的下一个字符,以便创建高效的标记器。

但是,我没有找到任何令人满意的解决方案。

QFile f("test.txt");
f.open(QIODevice::WriteOnly);
f.write("Hello world\nHello universe\n");
f.close();

f.open(QIODevice::ReadOnly);
QTextStream s(&f);
int i = 0;
while (!s.atEnd()) {
  ++i;
  qDebug() << "Peek" << i << s.device()->peek(3);
  QString v;
  s >> v;
  qDebug() << "Word" << i << v;
}

给出以下输出:

Peek 1 "Hel" # it works only the first time
Word 1 "Hello" 
Peek 2 "" 
Word 2 "world" 
Peek 3 "" 
Word 3 "Hello" 
Peek 4 "" 
Word 4 "universe" 
Peek 5 "" 
Word 5 ""

我尝试了几种实现方式,包括 QTextStream::pos() 和 QTextStream::seek()。它工作得更好,但 pos() 有问题(当文件太大时返回 -1)。

有没有人能解决这个反复出现的问题?提前谢谢你。

【问题讨论】:

  • 添加到日志s.device()-&gt;pos()s.device()-&gt;bytesAvailable() 以检查设备读取进度。这可能有助于定位问题。
  • 在第一个 QTextStream::operator>>: (pos = 0, bytesAvailable = 27) 之前。就在它之后直到结束:(pos = 27,bytesAvailable = 0)。 Qt 的错误行为似乎确实相关
  • 我检查了QTextStream code。看起来它总是尽可能多地缓存数据,并且无法禁用此行为。我期待它会在设备上使用 peek,但它只会以贪婪的方式读取。底线是在这种情况下你不能使用QTextStream
  • 是的。我还尝试将 QTextStream 和 QFile 设置为无缓冲(来自构造函数),但这也无济于事。
  • 我的看法是缺少像 QTextStream::peek(int size) 这样的函数。

标签: qt seek peek qtextstream


【解决方案1】:

你从QIODevice 窥视,然后你从QTextStream 读取,这就是为什么窥视只能工作一次。试试这个:

while (!s.atEnd()) {
      ++i;
      qDebug() << "Peek" << i << s.device()->peek(3);
      QByteArray v = s.device()->readLine ();
      qDebug() << "Word" << i << v;
}

很遗憾,QIODevice 不支持阅读单个单词,所以你必须自己结合峰值和阅读。

【讨论】:

  • 感谢您的关注。我写的例子非常简化。在我的具体示例中,我对集中使用 QTextStream::operator>>. 很感兴趣
  • 问题确实是 QTextStream::device() 与 QTextStream 不同步。而且QTextStream上没有直接的窥视功能。
  • 确实如此,但是由于没有读取 QIODevice 中的单词的方法,并且 pos() 有问题,我的建议是自己为 QIODevice 实现逐字读取并改用它QTextStream::operator>>.或者有什么理由一定是这个运营商?
  • 是的,你完全正确。事实上,在讨论过程中,我选择了这个解决方案并实现了它:-) 使用 QTextStream 编写一个简单而好看的代码非常方便。可惜这个类中没有 peek 函数,破坏了使用这个类编写真正的分词器的可能性(需要 peek 来解析模棱两可的语言)
  • @FabienRohrer IIRC,QTextStream 要么成功读取,要么保持输入不受干扰。因此,尝试读取一个数字应该没问题,如果失败,那么您可以读取一个单词。
【解决方案2】:

试试disable QTextStream::autoDetectUnicode。这可能会提前读取设备以执行检测并导致您的问题。

也设置一个编解码器以防万一。

添加到日志s.device()-&gt;pos()s.device()-&gt;bytesAvailable() 以验证这一点。


我检查了QTextStream code。看起来它总是尽可能多地缓存数据,并且无法禁用此行为。我期待它会在设备上使用 peek,但它只会以贪婪的方式读取。底线是您不能同时使用QTextStream 和峰值设备。

【讨论】:

  • 我尝试了 QTextStream::setAutoDetectUnicode(bool) 有或没有 QTextStream::setCodec("UTF-8") 的所有组合,问题仍然存在
猜你喜欢
  • 1970-01-01
  • 2014-02-10
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-29
  • 2011-03-12
相关资源
最近更新 更多