• 12006阅读
  • 11回复

[提问]QFile中map的问题 [复制链接]

上一主题 下一主题
离线xlttap
 

只看楼主 倒序阅读 楼主  发表于: 2011-04-08
假如我有一个大文本文件1G,我想用内存映射文件来实现,
我用QFile的map得到映射地址后,如何把里面的内容输出到
QTextEdit中显示呢?

QFile file("large_file.txt");
file.open(QFile::ReadOnly);

uchar *ptr = NULL;
qint64 size = file.size();
qint64 offset = 0;
qint64 read_size = 51200;
while(offset < size) {
       ptr = file.map(offset, read_size);
       // 这里怎么把ptr中的内容放到QTextEdit中?
    ......
      offset += read_size;
       file.unmap(ptr);
}

file.close();

// 或者我这样实现不对,有别的思路,请指教。
[ 此帖被xlttap在2011-04-08 13:59重新编辑 ]
我简单我快乐
离线linxy

只看该作者 1楼 发表于: 2011-04-08
#include <QtCore/QCoreApplication>
#include <QFile>
#include <iostream>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFile file( ":/file.txt" );

    if ( !file.open( QIODevice::ReadOnly ) )
    {
        return 1;
    }

    uchar* ptr = NULL;

    qint64 size = file.size();

    ptr = file.map( 0, size );

    for( int i=0; i<size; ++i )
    {
        std::cout << char( ptr );
    }

    file.unmap( ptr );

    file.close();

    return a.exec();
}
离线linxy

只看该作者 2楼 发表于: 2011-04-08
再贴一次,上面贴的有问题

#include <QtCore/QCoreApplication>
#include <QFile>
#include <iostream>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFile file( ":/file.txt" );

    if ( !file.open( QIODevice::ReadOnly ) )
    {
        return 1;
    }

    uchar* ptr = NULL;

    qint64 size = file.size();

    ptr = file.map( 0, size );

    for( int i=0; i<size; ++i )
    {
        std::cout << char( ptr );
    }

    file.unmap( ptr );

    file.close();

    return a.exec();
}
离线linxy

只看该作者 3楼 发表于: 2011-04-08
这个怎么显示不了??
离线linxy

只看该作者 4楼 发表于: 2011-04-08
ptr后面的index显示不了?
离线xlttap

只看该作者 5楼 发表于: 2011-04-08
回 1楼(linxy) 的帖子
你小文件这样可以,但是如果是一个很大的文件,
不可能把整个文件映射到内存吧。应该是映射一部分。
再者,对映射后的内容遍历,又是一个很慢的过程啊。
这样就没有体现内存映射的优势。
我简单我快乐
离线linxy

只看该作者 6楼 发表于: 2011-04-08
回 5楼(xlttap) 的帖子
作为一个参考例子,我就全部映射进去了,当然,你可以只映射一部分就行了,不一定要全部都映射进去啊,还有我记得用map不是将内容映射到内存中去的
离线xlttap

只看该作者 7楼 发表于: 2011-04-08
回 6楼(linxy) 的帖子
为什么我全部映射时,用setPlainText(QString((char*)ptr))正常,
而映射一部分时,setPlainText(QString((char*)ptr)) 这句会出错?
我gdb调试说这句出错。
我简单我快乐
离线linxy

只看该作者 8楼 发表于: 2011-04-08
回 7楼(xlttap) 的帖子
    uchar* ptr = NULL;


    qint64 size = file.size();

    quint64 block = 512;
    quint64 offset = 0;


    for ( offset; offset < size; )
    {
        ptr = file.map( offset, block );
        std::string str ( ptr, ptr + block );
        std::cout << str << std::endl;
        file.unmap( ptr );
        offset += block;

        if ( offset >= 1000 * block )
            break;
    }

    file.unmap( ptr );

    file.close();
离线linxy

只看该作者 9楼 发表于: 2011-04-08
不过对最后的那一块可能要进行判断,因为最后一块不一定就是512
离线roywillow

只看该作者 10楼 发表于: 2011-04-08
因为方括号内带个i会被解析成斜体,所以用i的循环的代码写在这里就会杯具……
不太懂map的作用,如果我想将文件中的字节一个一个读取出来的话用map会速度快一些吗?
我曾经尝试用QTableView来显示一个文件的所有二进制信息,但是发现处理起来很慢……
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线xlttap

只看该作者 11楼 发表于: 2011-04-08
我觉得用QTextEdit作显示的话,还是不用map,
因为,如果我一部分一部分映射,有可能这块数据
的最后一行是原始数据中某行的一部分,影响美观。

我现在还是改成用read读取文件中的一部分,一次读多少行。
进行显示。记住当前的offset,下次从当前位置再读取多少行。
我简单我快乐
快速回复
限100 字节
 
上一个 下一个