文件操作概述
1、Qt中IO操作的处理方式
(1)、Qt通过统一的接口简化了文件与外部设备的操作方式
(2)、Qt中的文件被看做是一种特殊的外部设备
(3)、Qt中的文件操作与外部设备操作相同
2、IO操作中的关键函数接口
注意:IO操作的本质:连续存储空间的数据读写
3、Qt中IO设备类型
(1)、顺序存储设备:只能从头开始顺序读写数据,不能指定数据的读写位置(串口)
(2)、随机存储设备:可以定位到任意位置进行数据读写(seek function函数)(文件)
4、Qt中IO设备 的继承层次图
5、QT文件操作类型
|------------------------|----------------------------------------------------------------------------------|
| QFile | QFile是Qt中用于文件操作的类 QFile直接支持文本文件:文件内容是可读的文本字符、 和数据文件:文件内容是直接的二进制数据的读写 |
| QFineInfo | 用于读取文件属性信息 |
| QTemPoraryFile | 安全创建全局唯一的临时文件、临时文件用于大数据传递或者进程间通信的场合 |
| QTextStream | 写入的数据全部转化为可读文本 |
| QDataStream | 写入的数据根据类型转换为二进制 |
| QBuffer | 缓冲区的本质为一段连续的存储空间、 QBuffer是qt中缓冲区相关的类 |
| QDir | 是Qt中功能强大的目录操作类 |
| QFileSystemWatcher | 用于监控文件和目录的状态变化(内容、重命名、删除) |
QFile操作
mainwindow.cpp:
cpp
#include "mainwindow.h"
#include <QApplication>
#define chineseToQString(pChineseText) QTextCodec::codecForName("GB2312")->toUnicode(pChineseText)
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
this->setWindowTitle("qfile test");
QWidget* w=new QWidget;
setCentralWidget(w);
buttonRead->setText("buttonRead");
buttonWrite->setText("buttonWrite");
QHBoxLayout* hlayout=new QHBoxLayout;
hlayout->addStretch(1);
hlayout->addWidget(buttonRead);
hlayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding));
hlayout->addWidget(buttonWrite);
hlayout->addStretch(1);
QVBoxLayout*container = new QVBoxLayout();
container->addLayout(hlayout);
container->addWidget(textEdit);
centralWidget()->setLayout(container);
this->resize(600, 400);
connect(buttonRead,&QPushButton::clicked,this,&MainWindow::on_readData);
connect(buttonWrite,&QPushButton::clicked,this,&MainWindow::on_writeData);
}
void MainWindow::on_readData()
{
QString path = QFileDialog::getOpenFileName(this,"open", "../", "TXT(*.txt)");
if(path.isEmpty() == false){
QFile file(path); //文件对象
bool isOk = file.open(QIODevice::ReadOnly);//打开文件,只读方式
if(isOk == true) {
#if 0
QByteArray array = file.readAll();//读文件,默认只识别utf8编码
textEdit->setText(QString(array)); //显示到编辑区
textEdit->setText(array);
#endif
QByteArray array;
while( file.atEnd() == false) {
//读一行
array += file.readLine();
}
textEdit->setText(array);
}
file.close();//关闭文件
//获取文件信息
QFileInfo info(path);
qDebug() << "文件路径:"<< info.path();
qDebug() << "文件名字:" << info.fileName().toUtf8().data();
qDebug() << "文件后缀:" << info.suffix();
qDebug() << "文件大小:" << info.size();
qDebug() << "文件创建时间:" <<
info.created().toString("yyyy-MM-dd hh:mm:ss");
qDebug() << info.exists();
qDebug() << info.isFile();
qDebug() << info.isReadable();
qDebug() << info.isWritable();
qDebug() << info.lastRead();
qDebug() << info.lastModified();//最后修改时间
}
}
void MainWindow::on_writeData()
{
QString path = QFileDialog::getSaveFileName(this, "save", "../", "TXT(*.txt)");
if(path.isEmpty() == false) {
QFile file; //创建文件对象
file.setFileName(path);//关联文件名字
bool isOk = file.open(QIODevice::WriteOnly);//打开文件,只写方式
if(isOk == true) {
QString str = textEdit->toPlainText();//获取编辑区内容
file.write(str.toUtf8()); //QString -> QByteArray
file.write(str.toStdString().data());//QString -> c++ string -> char *
//file.write(str.toLocal8Bit());//转换为本地平台编码
}
file.close();
}
}
mainwindow.h:
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGroupBox>
#include <QRadioButton>
#include <QStringList>
#include <QLineEdit>
#include <QGridLayout>
#include <QFormLayout>
#include <QTextCodec>
#include <QListWidget>
#include <QLabel>
#include <QStackedLayout>
#include <QTextEdit>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
#include <QDebug>
#include <QDateTime>
#include <QDataStream>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void on_readData();
void on_writeData();
private:
QPushButton *buttonRead = new QPushButton();
QPushButton *buttonWrite = new QPushButton();
QTextEdit *textEdit = new QTextEdit();
};
#endif // MAINWINDOW_H
运行结果:
qfile读写16进制数据
cpp
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QDataStream>
#include <QIODevice>
#define HexPrint(packet, len)\
do{\
QByteArray data((const char*)packet, len); \
QString hexString; \
for (int i = 0; i < data.size(); i++) { \
hexString += QString("%1 ").arg((quint8)data.at(i), 2, 16, QChar('0')); \
} \
qDebug() << hexString; \
}while(0);
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
writeDataToFile();
readDataFromFile();
}
void MainWindow::writeDataToFile(void)
{
QFile file("qfile_test.dat");
if (!file.open(QIODevice::WriteOnly)) {
// Handle error
return;
}
uint8_t data_buf[32] ={
0x55,0xAA,0xD9,0x6E,0x1A,0x00,0x04,0x00,0x1A,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
0x66,0xBB,0xD9,0x6E,0x1A,0x00,0x04,0x00,0x1A,0x00,0x01,0x00,0x00,0x00,0x00,0x00
};
QByteArray b_data((const char *)&data_buf,sizeof(data_buf));
qint64 i64WriteBytes = file.write(b_data);
if( b_data.length() != i64WriteBytes ){
qDebug()<<"write data len err";
}
file.close();
}
void MainWindow::readDataFromFile(void)
{
QFile file("qfile_test.dat");
if (!file.open(QIODevice::ReadOnly)) {
// Handle error
return;
}
QByteArray qbaData;
file.seek(0);
qbaData = file.readAll();
if( qbaData.length() != file.size() ){
qDebug()<<"read data len err";
}
qDebug()<<"read data:";
HexPrint(qbaData.data(),qbaData.size());
}
QDataStream操作
读写16进制数据
读写quint16、和quint32类型的数据:
cpp
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QDataStream>
#include <QIODevice>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
writeDataToFile();
readDataFromFile();
}
void MainWindow::writeDataToFile(void)
{
QFile file("test.dat");
if (!file.open(QIODevice::WriteOnly)) {
// Handle error
return;
}
QDataStream out(&file);
out.setByteOrder(QDataStream::LittleEndian); // 设置字节序为小端
out << (quint16)0x1234;// 写入16进制数据
out << (quint32)0xABCDEF12;
file.close();
}
void MainWindow::readDataFromFile(void)
{
QFile file("test.dat");
if (!file.open(QIODevice::ReadOnly)) {
// Handle error
return;
}
QDataStream in(&file);
in.setByteOrder(QDataStream::LittleEndian); // 设置字节序为小端
quint16 value16;
quint32 value32;
in >> value16; // 读取一个16位无符号整数
in >> value32; // 读取一个32位无符号整数
file.close();
qDebug("src:0x1234,read data: 0x%X\n",value16);// 使用读取的数据
qDebug("src:0xABCDEF12,read data: 0x%X",value32);
}
写到文件的数据:
从文件读取数据放置对应的类型的变量,变量打印如下:
读写uint8_t类型的数据buffer:
cpp
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QDataStream>
#include <QIODevice>
#define HexPrint(packet, len)\
do{\
QByteArray data((const char*)packet, len); \
QString hexString; \
for (int i = 0; i < data.size(); i++) { \
hexString += QString("%1 ").arg((quint8)data.at(i), 2, 16, QChar('0')); \
} \
qDebug() << hexString; \
}while(0);
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
writeDataToFile();
readDataFromFile();
}
void MainWindow::writeDataToFile(void)
{
QFile file("test.dat");
if (!file.open(QIODevice::WriteOnly)) {
// Handle error
return;
}
QDataStream out(&file);
uint8_t data_buf[32] ={
0x55,0xAA,0xD9,0x6E,0x1A,0x00,0x04,0x00,0x1A,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
0x66,0xBB,0xD9,0x6E,0x1A,0x00,0x04,0x00,0x1A,0x00,0x01,0x00,0x00,0x00,0x00,0x00
};
for(int i=0;i<sizeof(data_buf);i++){
out << data_buf[i];
}
file.close();
}
void MainWindow::readDataFromFile(void)
{
QFile file("test.dat");
if (!file.open(QIODevice::ReadOnly)) {
// Handle error
return;
}
QDataStream in(&file);
char data_buf[32];
for(int i=0;i<sizeof(data_buf)/8;i++){
in.readRawData(data_buf, 8);
HexPrint(data_buf,8);
}
}