QT5 文件读写操作

一、文件读写

QFile

  1. read读文件
  • 加载文件对象 QFile file(“文件地址”);
  • 打开加载的文件file.open(打开方式);
  • 操作文件
  • 关闭打开的文件file.colse();
void Widget::on_pushButton_clicked()
{
    QFile file("L:/qtpro/_qtApp/text/t.txt");
    file.open(QIODevice::ReadOnly | QIODevice::Text);
    QByteArray t = file.readAll();
    ui->text_r->setText(QString(t));
    file.close();
}
  1. wirte写文件
    以纯文本的形式读取要保存文件到QString对象 //ui->text_e->toPlainText();
  • 创建QFile 对象保存文件
  • 打开QFile对象
  • 写入文件操作
  • 关闭打开的文件;
void Widget::on_pushButton_2_clicked()
{
    QString e = ui->text_e->toPlainText();
    QFile file("L:/qtpro/_qtApp/text/e.txt");
    file.open(QIODevice::WriteOnly | QIODevice::Text);
    file.write(e.toUtf8());
    file.close();
}

细节优化处理

  • read文件添加读取文件选择项 QFileDialog::getOpenFileName();
  • 打开文件是否成功的判断;
  • 按行读取文件,可控制读取行数与每行字符数;
  • write文件创建保存路径QFileDialog::getSaveFileName();
void Widget::on_pushButton_clicked()
{
    QFile file;
    QString f = QFileDialog::getOpenFileName(this, QString("选择文件"), QString("/"),QString("TEXT(*.txt)"));
    file.setFileName(f);
    if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QByteArray t ;
        while(!file.atEnd())
        {
            t += file.readLine();
        }
        ui->text_r->setText(QString(t));
        file.close();
    }
}

void Widget::on_pushButton_2_clicked()
{
    QString e = ui->text_e->toPlainText();
    QFile file;
    file.setFileName(QFileDialog::getSaveFileName(this, QString("保存路径"), QString("/"),QString("TEXT(*.txt)")));
    file.open(QIODevice::WriteOnly | QIODevice::Text);
    file.write(e.toUtf8());
    file.close();
}

各编码转换
QString -> QByteArray QString.toUtf8();
QByteArray -> std::string QByteArray.toStdString();
std::string -> char * string.date();

常用静态函数:
QFileDialog::getOpenFileName() //获取指定文件路径名返回QString
QFileDialog::getExistingDirectory() //获取指定路径返回QString
QFileDialog::getSaveFileName() //获取指定保存路径名返回QString

辅助配合使用的类:
QFileInfo class获取文件信息;
QFileInfo类用于读取文件的属性信息

QFile file(f);
QFileInfo info(file);

qDebug() << info.exists();
qDebug() << info.isFile();
qDebug() << info.isReadable();
qDebug() << info.isWritable();
qDebug() << info.created();
qDebug() << info.lastRead();
qDebug() << info.lastModified();
qDebug() << info.path();
qDebug() << info.fileName();
qDebug() << info.suffix();
qDebug() << info.size();

QFile用例:

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
   Q_OBJECT
public:
   explicit Widget(QWidget *parent = 0);
   ~Widget();

private slots:
   void on_readButton_clicked();
   void on_writeButton_clicked();
private:
   Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QFileInfo>
#include <QDateTime>
#include <QDebug>
#include <QDataStream>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_readButton_clicked()
{
    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
            //默认只识别utf8编码
            QByteArray array = file.readAll();
            //ui->textEdit->setText(QString(array));
            ui->textEdit->setText(array);
 #endif
            QByteArray array;
            while (file.atEnd() == false)
            {
                array += file.readLine();
            }
            ui->textEdit->setText(array);

        }
        file.close();

        QFileInfo info(path);
        qDebug()<<info.fileName();
        qDebug()<<info.suffix();
        qDebug()<<info.size();
        qDebug()<<info.created().toString("yyyy-MM-dd hh:mm:ss");
    }
}

void Widget::on_writeButton_clicked()
{
    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 = ui->textEdit->toPlainText();
            file.write(str.toUtf8());
            //file.write((str.toStdString().data()));
        }
        file.close();
    }
}

二、文本流、数据流与缓冲区

QT中将文件分为文本文件和数据文件,文本文件内容是可读的文本字符,数据文件的内容是二进制数据。

QFile直接支持文本文件和数据文件的操作,主要函数接口如下:
qint64 read( char * data, qint64 maxSize) //数据流读取
QByteArray read( qint64 maxSize) //文本流方式读取
QByteArray readAll() //文本流方式读取
QByteArray readLine()//文本流方式读取
qint64 write(const char * data, qint64 maxSize)
qint64 write(const QByteArray & byteArray)

简化文本文件和数据文件的读写操作,QT提供了QTextStream和QDataStream辅助类。
QTextStream可将写入的数据全部转换为可读文本。
QDataStream可将写入的数据根据类型转换为二进制数据。
QTemporaryFile是QT中的临时文件操作类,用来安全创建全局唯一的临时文件,QTemporaryFile对象销毁时对应的临时文件将被删除,临时文件的打开方式为QIODevice::ReadWrite,临时文件常用于大数据传递或者进程间通信场合。

QTemporaryFile tempFile;
if( tempFile.open() )
{  
    tempFile.write("D.T.Software");
    tempFile.close();
}

1. QTextStream

用例:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void writeData();
    void readData();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QFileDialog>
#define cout qDebug()<<"["<<__FILE__<<":"<<__LINE__<<"]"
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    writeData();
    readData();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::writeData()
{
    QFile file;
    file.setFileName("../demo.txt");

    bool isOK = file.open(QIODevice::WriteOnly);
    if(true == isOK)
    {
        QTextStream stream(&file);
        //指定编码
        stream.setCodec("UTF-8");
        stream << QString("hello world")<<250;
        file.close();
    }
}

void Widget::readData()
{
    //这么读有问题
    QFile file;
    file.setFileName("../demo.txt");

    bool isOK = file.open(QIODevice::ReadOnly);
    if(true == isOK)
    {
        QTextStream stream(&file);
        //指定编码
        stream.setCodec("UTF-8");
        QString str;
        int a;
        stream >>str>>a;
        cout<<str<<a;
        file.close();
    }
}

void Widget::on_pushButton_clicked()
{
    QString path = QFileDialog::getOpenFileName(this,
                                                "read",
                                                "../"
                                                );
    if(false == path.isEmpty())
    {
        QFile file;
        file.setFileName(path);
        bool isOK = file.open(QIODevice::ReadOnly);
        if(true == isOK)
        {
            QTextStream stream(&file);
            stream.setCodec("UTF-8");
            QString str = stream.readAll();
            ui->textEdit->setText(str);
            file.close();
        }
    }

}

2. QDataStream

  • 创建流对象 QDataStream date;

  • 将数据存在流中 date >> a >> b;
    int a= xxxx;
    string b = “xxxxxxxxx” ;

    扫描二维码关注公众号,回复: 5480514 查看本文章
  • 从流中取出数据 date << aa << bb;
    int aa;
    string bb;

QDataStream在不同的QT版本中数据流文件格式可能是不同的,如果数据流文件需要在不同版本的QT程序间传递时需要考虑版本问题。
void setVersion(int v)
int version() const
QTextStream Class

文本方式操作文件:
创建流对象 QDataStream date;
date.setCodec();支持对文件读取编码设置(有效解决乱码问题)
在写出二进制时,如果需要仅仅写入原始的内存,记得使用函数
int QDataStream::writeRawData(const char *s, int len)
而不是下面的,下面的writeBytes会自动写入额外长度等数据
QDataStream &QDataStream::writeBytes(const char *s, uint len)

QDataStream 用例1:

    QFile fileRead("data_in.bin");
    //已读写方式打开文件,
    //如果文件不存在会自动创建文件
    if(!fileRead.open(QIODevice::ReadWrite)){
        //ReadOnly文件不存在,打开失败
        //WriteOnly文件不存在,会自动创建文件
        //ReadWrite文件不存在,会自动创建文件
        //Append文件不存在,会自动创建文件
        //Truncate文件不存在,打开失败
        //Text文件不存在,打开失败
        //Unbuffered文件不存在,打开失败
        qDebug()<<"打开失败";
        return;
    }
    QDataStream in(&fileRead);
    int  nTotalSize = fileRead.size();

    fileRead.seek(500);

    char* ucEchoDataBin = new char[nTotalSize];
    in.readRawData((char *)ucEchoDataBin, nTotalSize);
    fileRead.close();

    QFile file("data_out.bin");
    //已读写方式打开文件,
    //如果文件不存在会自动创建文件
    if(!file.open(QIODevice::ReadWrite | QFile::Truncate)){
        //ReadOnly文件不存在,打开失败
        //WriteOnly文件不存在,会自动创建文件
        //ReadWrite文件不存在,会自动创建文件
        //Append文件不存在,会自动创建文件
        //Truncate以重写的方式打开,在写入新的数据时会将游标设置在文件开头
        //Text文件不存在,打开失败
        //Unbuffered文件不存在,打开失败
        qDebug()<<"打开失败";
        return;
    }
	quint8 ucEchoData[1008];
	
    QDataStream out(&file);
    out.writeRawData((const char*)ucEchoData,1008);
    
    //关闭文件
    file.close();    

QDataStream 用例2:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void writeData();
    void readData();
private:
    Ui::Widget *ui;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QDataStream>
#include <QTextStream>
#include <QFile>
#include <QDebug>

#define cout qDebug()<<"["<<__FILE__<<":"<<__LINE__<<"]"
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    writeData();
    readData();
}

Widget::~Widget()
{
    delete ui;
}
void Widget::writeData()
{
    QFile file("../fff.txt");
    bool isOK = file.open(QIODevice::WriteOnly);
    if (true == isOK)
    {
        //创建数据流,和file文件关联
        //往数据流中写数据,相当于往文件里写数据

        QDataStream stream(&file);
        stream<<QString("hello world")<<250;

    }
    file.close();
}

void Widget::readData()
{
    QFile file("../fff.txt");
    bool isOK = file.open(QIODevice::ReadOnly);
    if (true == isOK)
    {
        //创建数据流,和file文件关联
        //往数据流中读数据,相当于往文件里读数据
        QString str;
        int a;
        QDataStream stream(&file);
        stream>>str>>a;
        cout<<str<<a;
    }
    file.close();
}

3. QBuffer

QBuffer类为QByteArray提供QIODevice接口。

目前先理解为一个创建一个缓存文件;
QT中预定义了缓冲区的类QBuffer,可以将缓冲区看成一种特殊的IO设备,文件流辅助类可以直接用于操作缓冲区。QBuffer缓冲区写入和读取的数据必须是同一种数据类型,不能混合多种数据类型。

QBuffer的使用场合:
A、线程间不同类型的数据传递
B、缓存外部设备中的数据返回
C、数据读取速度小于写入速度

QBuffer用例:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QBuffer>//内存文件
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    QBuffer memFile;
    memFile.open(QIODevice::WriteOnly);

    memFile.write("hello");
    memFile.write("world");

    memFile.close();

    qDebug()<<memFile.buffer();

    QBuffer memFile1;
    memFile1.open(QIODevice::WriteOnly);
    QDataStream stream(&memFile1);
    stream<<QString("测试")<<250;
    memFile1.close();

    qDebug()<<QString(memFile.buffer()).toUtf8().data();//输出有问题
//输出正确
    memFile1.open(QIODevice::ReadOnly);
    QDataStream in(&memFile1);
    QString str;
    int a;
    in>>str>>a;
    memFile1.close();
    qDebug()<<str.toUtf8().data()<<a;
}

Widget::~Widget()
{
    delete ui;
}

总结:读写操作主要方法有read();readAll();readline(),write();

附录:
目录操作
1、QDir QT中提供了目录操作类QDir,QDir功能如下:
A、目录分隔符统一使用’/’
B、能够对目录进行任意操作(创建、删除、重命名)
C、能够获取指定目录中的所有条目(文件和文件夹)
D、能够使用过滤字符串获取指定条目
E、能够获取系统中的所有根目录

QDir使用方法如下:

 QDir dir;
    QString path("../qt/test");
    if(!dir.exists())
    {
        dir.mkdir(path);
    }
    else
    {
        dir.cd(path);
        QStringList list = dir.entryList();
        for(int i = 0; i < list.count(); i++)
        {
            qDebug() << list[i];
        }
    }

//计算文件大小
unsigned int FileSize(QString path)
{
    QFileInfo info(path);
    unsigned int ret = 0;
    if(info.isFile())
    {
        ret = info.size();
    }
    else if(info.isDir())
    {
        QDir dir(path);
        QFileInfoList list = dir.entryInfoList();
        for(int i = 0; i < list.count(); i++)
        {
            if((list[i].fileName() != ".") && (list[i].fileName() != ".."))
            {
                ret += FileSize(list[i].absoluteFilePath());
            }
        }
    }
    return ret;
}

2、QFileSystemWatcher
QT中预定义了用于监控文件和目录变化的类QFileSystemWatcher,

QFileSystemWatcher主要功能如下:

A、能够监控特定目录和文件的状态
B、能够同时对多个文件和目录进行监控
C、当目录或文件发生改变时触发信号
D、通过信号与槽的机制捕捉信号并做出响应

通常要使用QFileSystemWatcher需要自定义文件监视类。

转自:https://www.cnblogs.com/flowingwind/p/8336159.html

猜你喜欢

转载自blog.csdn.net/qing666888/article/details/87873591
今日推荐