一.
QT通过QIODevice为输入输出提供支持。QIODevice是一个封装能够读写字节块”设备“的强有力提取器。
QT包括如下的QIODevice类:
QFile 在本地文件系统和嵌入式资源中存取文件。
QTemporaryFile 在本地文件系统中创建并存取临时文件
QBuffer 从QByteArray中读取或写入数据
QProcess 运行外部程序并处理进程间通信
QTcpSocket 利用TCP在网络上传输数据
QUdpSocket 在网络上发送或接受UDP数据报
QSslSocket 利用SSL/TLS在网络上传输加密数据流
二.
文件读写包括二进制文件读写和文本文件读写
我们先来看看二进制文件读写:
QT中读写二进制文件最简单的方法是通过实例化一个QFile打开文件,然后通过QDataStream对象存取它。QDataStream支持QList<T> QMap<K,T>等容器类以及整形,双精度等基本的C++类,和其它的QT基本类型:QByteArray,QFont,QImage,QPixmap,QString,QVaruiant等等。
例子:
上半部分写文件,下面半部分读文件,这个例子是C++ GUI Qt4编程这本书上的。
#include <QtCore/QtCore>
#include <QApplication>
#include <QImage>
#include <QColor>
#include <QLabel>
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
/* QImage image(":/image/copy.png"); //创建一个图片变量
QMap<QString,QColor> map; //映射表
map.insert("red",Qt::red);
map.insert("green",Qt::green);
map.insert("blue",Qt::blue);
QFile file("hello.dat");
if(!file.open(QIODevice::WriteOnly))
{
qDebug()<<"failed!";
return -1;
}
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_3);
out<<quint32(0x12345678)<<image<<map;
qDebug()<<"success!";
file.close();*/ //必须要close,要不然写不进去
quint32 n; //读取时的类型一定要和写入时一样
QImage image;
QMap<QString,QColor> map;
QFile file("hello.dat");
if(!file.open(QIODevice::ReadOnly))
{
qDebug()<<"failed!";
return 1;
}
QDataStream in(&file);
in.setVersion(QDataStream::Qt_4_3);
in>>n>>image>>map;
qDebug()<<QString::number(n);
QLabel *label=new QLabel;
label->setPixmap(QPixmap::fromImage(image));
label->show();
qDebug()<<"success";
QMap<QString,QColor>::const_iterator i;
for(i=map.constBegin();i!=map.constEnd();++i)
qDebug()<<i.key()<<":"<<i.value();
file.close();
return app.exec();
}
然后来看一下文本文件的读写
虽然二进制文件格式比通常基于文本的格式更加紧凑,但是无法阅读和编辑。QT提供了QTextStream类读写纯文本文件以及如HTML,XML和源代码等其它文本格式的文件。
写文本文件很容易:
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
QFile file("hello.txt");
if(!file.open(QIODevice::WriteOnly))
{
qDebug()<<"failed";
return 1;
}
QTextStream out(&file);
out<<"hello world"<<123<<endl;
file.close();
return app.exec();
}
但是读文本比较麻烦,因为文本数据从根本上来说是不确定的。
out<<"hello"<<"world";
读取时如果用in>>str1>>str2,那么str1会是”helloworld“,而str2是空,因为它不知道字符串的长度。
解析器通常通过在QChar上使用>>来一个字符一个字符的读取,或者用QTextStream::readline来一行一行读取,或者QTextStream::readAll()来一次性全部读取。
一行读取
QTextStream in(&file);
while(!in.atEnd())
{
QString line=in.readLine();
}
也可以用分割器来分割一行从而获取各个部分的值。
QTextStream in(&file);
while(!in.atEnd())
{
QString line=in.readLine();
QStringList fields=line.split();
QString line1=fields.takeFirst(); //takefirst()会返回列表中的第一项然后删除它
QString line2=fields.takeFirst();
QString line3=fields.takeFirst();
}
我觉得写文件的时候最好是定义一个格式,读的时候会方便很多。
字符读取
const int TabSize = 8;
int endlCount = 0;
int spaceCount = 0;
int column = 0;
QChar ch;
while (!in.atEnd()) {
in >> ch;
if (ch == '\n') {
++endlCount;
spaceCount = 0;
column = 0;
} else if (ch == '\t') {
int size = TabSize - (column % TabSize);
spaceCount += size;
column += size;
} else if (ch == ' ') {
++spaceCount;
++column;
} else {
while (endlCount > 0) {
out << endl;
--endlCount;
column = 0;
}
while (spaceCount > 0) {
out << ' ';
--spaceCount;
++column;
}
out << ch;
++column;
}
}
out << endl;
int endlCount = 0;
int spaceCount = 0;
int column = 0;
这三个只是计数器,看看有多少行什么的