QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2490|回复: 14

qt数据读入内存以及内存操作问题

[复制链接]
发表于 2004-12-19 18:47:52 | 显示全部楼层 |阅读模式
qt下用什么函数把数据读入内存比较好呢?
类似于VC的CFile.ReadHuge()
我在QFile里找到了readBlock
Q_LONG QFile::readBlock ( char * p, Q_ULONG len ) [虚]
从这个文件中读取最多maxlen字节到p并且返回实际读取的字节数量。

如果就用readBlock函数
请问我怎么给里面的q分配内存呢,如何锁定以及解锁呢?
谢谢!
发表于 2004-12-19 19:03:57 | 显示全部楼层
看例子吧
[code:1]
bool SysSetting::loadSetting( )
{
    userList.clear();
    QString fullPath = QDir::homeDirPath() + QString("/.eva/") + filename;

    QFile file(fullPath);
    if(!file.open(IO_ReadOnly)){
            return FALSE;
    }       
    // 预处理
    Q_UINT32 qq;
    char *pwd;
    Q_UINT8 flag;
   
    QDataStream stream(&file);
    stream>>(Q_UINT32&)lastIndex;
    while(!stream.atEnd()){
        stream>>qq;
        pwd = (char *)malloc(16 * sizeof(char));
        stream.readRawBytes(pwd, 16);
        stream>>flag;
        loginRecord *record = new loginRecord();
        record->id = qq;
        record->md5Pwd = (Q_UINT8 *)pwd;
        record->flag = flag;
        
        userList.append(record);               
    }
    file.close();
   
    return TRUE;
}
[/code:1]

如果你用这个Q_LONG QFile::readBlock ( char * p, Q_ULONG len ),
你就要确定最多的读入字节数, 当然返回值最好捕捉一下,看看有没有异常。
回复

使用道具 举报

 楼主| 发表于 2004-12-19 19:50:16 | 显示全部楼层
QDataStream stream(&file);
构造数据流
pwd = (char *)malloc(16 * sizeof(char));
stream.readRawBytes(pwd, 16);
读入数据到pwd中
对吧?
但是这样并没有锁定内存阿
回复

使用道具 举报

发表于 2004-12-19 19:59:21 | 显示全部楼层
能否解释一下,什么叫做“锁定内存”, 我不太懂?
大概是什么意思?
回复

使用道具 举报

 楼主| 发表于 2004-12-19 20:12:25 | 显示全部楼层
这样,我在VC中用的分配,锁定,解锁的函数是
GlobalAlloc,GlobalLock,GlobalUnlock
类似这样的
回复

使用道具 举报

发表于 2004-12-19 20:19:12 | 显示全部楼层
VC用过,但不是很熟, 你能说一下这几个函数是完成什么功能的,

你去查查QMutex, 但它不是对内存锁定的,Assistant上面很全。
回复

使用道具 举报

 楼主| 发表于 2004-12-19 20:35:46 | 显示全部楼层
我的理解GlobalAlloc应该和malloc差不多的分配内存,GlobalLock就是锁定住这块内存,不让别的进程来使用,保证数据不会被更改.
再问一下
在代码中我如何可以看到读入数据流以及内存的数据是否正确呢?
比如我想用一个QLabel把数据显示在窗口
用QLabel *label = new QLabel("&pwd", 0)显示内存的数据可以么?
显示stream该用什么呢?
回复

使用道具 举报

发表于 2004-12-19 20:54:48 | 显示全部楼层
[quote:a2e8578a36="Cryspin"]我的理解GlobalAlloc应该和malloc差不多的分配内存,GlobalLock就是锁定住这块内存,不让别的进程来使用,保证数据不会被更改.
再问一下
在代码中我如何可以看到读入数据流以及内存的数据是否正确呢?
比如我想用一个QLabel把数据显示在窗口
用QLabel *label = new QLabel("&pwd", 0)显示内存的数据可以么?
显示stream该用什么呢?[/quote]

1.锁定内存,我没有用过,也不知道这样的方法,sorry,不过,如果出现了你说的情况, 有两种可能,一个是其他程序访问到你的程序了,这应该会出现core dump,或者说crash,这是系统负责管理的, 另一种是你自己的程序访问了这块内存,这个系统不管,只有程序员自己管理了吧,只有写程序的时候考虑全面了。 也许有这样的方法,但是我不清楚。

2.stream是没法直接显示的,你还没有让它读,只有让它读出了,你接收,才能显示。你说得不太清楚,显示数据是很容易得事情(label->setText(), 或者 printf)
[code:1]
QString str;
stream >>str;
label->setText(str); // printf("str:%s\n", str.ascii());
[/code:1]
可能我对你的问题理解的有误.
回复

使用道具 举报

 楼主| 发表于 2004-12-19 21:18:47 | 显示全部楼层
你说的是对的,我前面不太明白Qdatastream的结构
我按照你给出的代码,写了一小段

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QFile file("/home/cryspin/filedata/hough.txt");
    QDataStream stream(&file);
    char *pwd;
    QString str;            

    pwd = (char *)malloc(16 * sizeof(char));
    stream.readRawBytes(pwd, 16);
    stream >>str;
    QLabel *label = new QLabel(str, 0);
    app.setMainWidget(label);
    label->show();
    return app.exec();
}

但是执行的时候出错,
提示:
QFile::readBlock: File not open
terminate called after throwing an instance of 'std::bad_alloc'
  what():  St9bad_alloc
已放弃

改动一些代码调试发现是
QDataStream stream(&file)
这句并没有读出数据来

代码我写的有错么?
回复

使用道具 举报

发表于 2004-12-19 21:23:11 | 显示全部楼层
看看你出错的提示
QFile::readBlock: File not open


我给的代码有这样几行
[code:1]
    if(!file.open(IO_ReadOnly)){
            return FALSE;
    }
[/code:1]

你没有打开文件, 当然读不出来了。
回复

使用道具 举报

 楼主| 发表于 2004-12-19 21:38:36 | 显示全部楼层
sorry,前面是我没注意 :-(

添加了之后还是有错误
经过修改发现错误在这一句
stream >>str;
提示:
terminate called after throwing an instance of 'std::bad_alloc'
  what():  St9bad_alloc
已放弃
回复

使用道具 举报

发表于 2004-12-19 21:53:29 | 显示全部楼层
, 没注意, 你用的是QDataStream, 和QTextStream不大一样

你换成QTextStream试试
回复

使用道具 举报

 楼主| 发表于 2004-12-19 22:12:42 | 显示全部楼层
换作QTextStream是可以显示
不过我以后需要的还是不能仅仅是.txt格式
需要打开.bmp文件读取里面的数据,这个时候用QTextStream应该不可以吧
回复

使用道具 举报

发表于 2004-12-19 22:34:44 | 显示全部楼层
如果你要用QDataStream来读取的话,也是可以的,
你必须了解文件的结构。

像文件中有不定长的结构,一般来说有两种简单的办法来定义它
1. 在他前面一个占固定长度的数(N个bytes)来说明它后面变长结构的长度(这就是为什么BMP文件要有文件头,文件头的格式是定死的,通过读取文件头,你就知道后面的格式和长度了)
2. 用一个特殊的分隔符来分隔(这个效率不高,很少用)

读的时候就可以处理了

这是简单的例子
[code:1]
QDataStream stream(file);
int len;
stream>>len;
char *str = (char *)malloc((len+1) * sizeof(char));
stream>>readRawBytes(str, len);
str[len] = 0x00;
[/code:1]

至于分隔符么, 就麻烦一点,效率不高, 读一个判断一次,是不是分隔符,不是
放入缓存中, 是就是下一个字段了。


如果你要对文件有更多的控制,比如随机访问,那么QDataSteam 和 QTextStream 几都不
适合了, 用QFile吧, 提供了更多对文件的控制,不过越底层的类你要处理的东西也就越多。了。
回复

使用道具 举报

发表于 2004-12-22 17:33:37 | 显示全部楼层
多看看QFile, QDataStream, QTextStream的文档吧
里面例子很多的
good luck
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-6 21:26 , Processed in 0.053193 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表