2014-09-13 68 views
1

我需要创建'tail -5 myfile'的Qt5/C++等效命令(不使用shell命令,我找到了几个stackoverflow引用来寻找X字节前文件结束,然后阅读前进,但我希望有更好的东西。向后查找Qt5/C++中的文本文件(尾部文件)

是否有更好/更快的方式与可用的Qt函数,或可能内存映射(文件的一部分)?(文件中问题可以是巨大的,所以这是相对高效的存储器)

+0

那么你想要做什么?你想读取文件的最后N个字节? 'QFile'具有查找功能。 – sashoalm 2014-09-13 13:03:01

+0

你是什么意思“更好的东西”?即使你使用'head -5',你仍然可以以一定大小的块读取文件,缓冲区可能只是隐藏在你的隐藏库和操作系统中。当向后读时,你只需要自己做。 – hyde 2014-09-13 14:02:35

+0

我正在尝试读取文本文件的最后5行(\ n行分隔符)。 linux命令'tail'显示文本文件的最后X行。 – TSG 2014-09-13 14:35:26

回答

3

正如sashoalm说,使用seek()方法,例如:

QElapsedTimer tmr; 
tmr.start(); 
QFile file("path"); 
if(file.open(QIODevice::ReadOnly)) 
{ 
qint64 num = 10; 
qint64 fileSize = file.size(); 
qDebug() << fileSize; 
file.seek(fileSize - num); 
qDebug() << file.read(num); 
qDebug() <<"reading took" << tmr.elapsed()<< "ms"; 
file.close(); 
} 

性能比较:

我有一个文件~11 Gb下一个输出。

size 11768585585 
"???G?t??" 
reading took 23 ms 

程序没有增加RAM的用法。对于小文件(~1Gb)我有0ms。我认为这是正常的速度。

编辑:

做这样的事情在Qt尾巴实用程序可以在明年的方式。我不认为这种方式非常正确,并且具有很大的性能,但它比读取所有文件和解析它要好。我们不能读取结束文件开始与一些魔术readLineFromEnd()方法,所以尽量用下一个:

QElapsedTimer tmr; 
tmr.start(); 
QFile file("path"); 
if(file.open(QIODevice::ReadOnly)) 
{ 
    file.seek(file.size()-1); 
    int count = 0; 
    int lines = 5; 
    while ((count < lines) && (file.pos() > 0)) 
    { 
     QString ch = file.read(1); 
     file.seek(file.pos()-2); 
     if (ch == "\n") 
      count++; 
    } 
    qDebug() << file.readAll(); 

qDebug() <<"reading took" << tmr.elapsed()<< " ms"; 
file.close(); 
} 

输出为8Kb txt文件:

reading took 2 ms . 

输出为~8Mb txt文件(这是日志文件):

reading took 1 ms 

是的,它具有较低的性能,但它是一项复杂的任务。有趣的是,需要多少时间才能做到这一点,但无论如何1和2毫秒是(可能)好结果。

+0

这不读取行(不是问题指的是'tail' - 这是一个用于打印出文件的最后X行的linux命令)。这只是读取n个字节 – TSG 2014-09-13 14:37:39

+0

@GenerationDSystems请看我的编辑,也许它会很有用。 – Chernobyl 2014-09-13 15:26:14

+0

这种方法看起来不太优雅......内存映射文件怎么样?如何将块读入QString并使用indexOf作为换行符等 – TSG 2014-09-13 15:42:21