今天在项目中碰到了一个问题,就是将被控主机注册表发送到控制端来显示,要尽可能模拟真实的注册表结构和风格。注册表分为两块,树状图和右边的表格视图是同步变化的,即双击一个树节点(子键),相应的树的子节点(子键)就会被加载,同时该节点(子键)对应的键值名、键值类型、键值也要在表格视图上显示出来,并且,当再双击另一个节点时,整个表格的数据要被新的子键的相应键值覆盖。虽然树状图的节点可以暂时保存在内存里,但表格视图上的数据却没办法保存,每次双击一个已经被展开过的节点都要重新请求键值,严重减缓了客户端的速度,这时想到了把每个已经加载过子键对应的表格视图键值都保存在本地文件中,然后再次双击该节点时,就可以直接从本地文件中读取,然后显示在表格视图上,这样省去了重复向远程被控端请求的时间。
然而用QT读写文件,我还刚接触,所以在查询了一些资料后,尝试着、并且坚持着把读写文件给成功完成了。成功的实现了不用重复请求远控端的方法。
QT中的读和写文件的方式也有很多,这是我用到的写和读(QTextStream):
写:
/*
* 将注册表子键值写进文件
*/
void RegistryWindow::writeIntoFileOfKeyValueTable(QString keyName,QString name,QString type,QString data)
{
//创建文件夹
if (!QDir::current().exists("keyValueTable"))
{
QDir::current().mkdir("keyValueTable");
}
QString re = keyName.replace(QRegExp("\\\\"),"@"); //正则表达式,@来代替分隔
//创建文件
QFile file("./keyValueTable/" + re +".txt");
if(!file.open(QIODevice::WriteOnly|QIODevice::Append))
{
QMessageBox::information(this,QStringLiteral("打开文件失败!"),file.errorString());
}
QTextStream fileOut(&file);
// fileOut.setCodec("UTF-8"); //unicode UTF-8 ANSI
fileOut << name << "$" << type << "$" << data << "\n";
file.flush();
file.close();
}
读:
/*
* 将文件中的注册表键值读出,并显示到注册表键值表格上
*/
void RegistryWindow::readFromFileOfKeyValueTable(QString keyName)
{
QString re = keyName.replace(QRegExp("\\\\"),"@");
//创建文件
QFile file("./keyValueTable/" + re +".txt");
//打开文件
if(!file.open(QIODevice::ReadOnly))
{
QMessageBox::information(this,QStringLiteral("打开文件失败!"),file.errorString());
}
QTextStream fileIn(&file);
QString str = fileIn.readLine(0);
while (str.contains("$"))
{
qDebug() << str;
QStringList strList = str.split("$");
QTextCodec *codec = QTextCodec::codecForLocale();//显示汉字的
//最终要存储的键值
QIcon *resultValueIcon;
QString resultValueName = strList.at(0);
QString resultValueType = strList.at(1);
QString resultValueData = strList.at(2);
//REG_DWORD类型的键值
if (QString(resultValueType).contains("REG_DWORD"))
{
resultValueIcon = new QIcon(":/Images/Resources/reg_011110.png");
}
//REG_BINARY类型的键值
else if (QString(resultValueType).contains("REG_BINARY"))
{
resultValueIcon = new QIcon(":/Images/Resources/reg_011110.png");
}
//REG_SZ\REG_EXPAND_SZ\REG_MULTI_SZ类型的键值
else
{
resultValueIcon = new QIcon(":/Images/Resources/reg_ab.png");
}
//键值名称
QTableWidgetItem *itemName = new QTableWidgetItem;
itemName->setIcon(*resultValueIcon);
itemName->setText(resultValueName);
//itemName->setText(codec->toUnicode(keyInfo.valueName));
//键值类型
QTableWidgetItem *itemType = new QTableWidgetItem;
itemType->setText(resultValueType);
//键值数据
QTableWidgetItem *itemData = new QTableWidgetItem;
itemData->setText(resultValueData);
myTableWidget->setRowCount(myTableWidget->rowCount()+1);
myTableWidget->setRowHeight(myTableWidget->rowCount()-1,20);//设置行高
myTableWidget->setItem(myTableWidget->rowCount()-1,0,itemName);
myTableWidget->setItem(myTableWidget->rowCount()-1,1,itemType);
myTableWidget->setItem(myTableWidget->rowCount()-1,2,itemData);
str = fileIn.readLine(0);
}
}