Qt 中的文件操作

目录

1、QT中的IO操作 

2、QFile、QFileInfo

2、QTemporaryFile

3、QTextStream 与 QDataStream 

4、QBuffer

5、QDir

6、文件系统监视器 


1、QT中的IO操作 

QT中IO操作的处理方式 

-Qt通过统一的接口简化了文件与外部设备的操作方式 

-Qt中的文件被看作一种特殊的外部设备 ,Qt中的文件操作与外部设备的操作相同 

IO操作中的关键函数接口 

         -打开设备: bool open(OpenMode mode) 

         -读取数据:QByteArray read(qint64 maxSize) 

         -写入数据:qint64 write(const QByteArray& byteArray) 

         -关闭设备: void close() 

IO操作的本质:连续存储空间的数据读写 (内存,硬盘、串口、USB口等)

Qt中IO设备的类型

 -顺序存取设备 :只能从头开始顺序的读写数据,不能指定数据的读写位置

 -随机存取设备 :可以定位到任意的位置进行数据的读写(seek function) 

Qt中IO设备的继承层次图 

2、QFile、QFileInfo

QFile是Qt中用于文件操作的类 ,QFile对象对应到计算机上的一个文件 

QFilelnfo类用于读取文件属性信息 

#include <QtCore/QCoreApplication>
#include <QFile>
#include <QByteArray>
#include <QFileInfo>
#include <QDateTime>
#include <QDebug>


void write(QString f)
{
    QFile file(f);

    if(file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        file.write("QQ: 111\n");
        file.write("From: 222 \n");

        file.close();
    }

}

void read(QString f)
{
    QFile file(f);

    if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QByteArray ba = file.readAll();

        QString s(ba);

        qDebug() << s;
    }
}

void info(QString f)
{
    QFile file(f);
    QFileInfo info(file);

    qDebug() << info.exists();
    qDebug() << info.isFile();
    qDebug() << info.isReadable();
    qDebug() << info.isWritable();
    qDebug() << info.created();//使用QDateTime头文件
    qDebug() << info.lastRead();
    qDebug() << info.lastModified();
    qDebug() << info.path();
    qDebug() << info.fileName();
    qDebug() << info.suffix();
    qDebug() << info.size();

}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //write("C:\\Users\\wss\\Desktop\\test.text");
    //write("C:/Users/wss/Desktop/test.text");
    
    //read("C:/Users/wss/Desktop/test.text");

    info("C:/Users/wss/Desktop/test.text");

    return a.exec();
}

 

 

2、QTemporaryFile

Qt中提供了临时文件操作类QTemporaryFile

         -安全地创建一个全局唯一的临时文件 ,当对象销毁时对应的临时文件将被删除 

         -临时文件的打开方式为QIODevice::ReadWrite (默认)

         -临时文件常用于大数据传递或者进程间通信的场合 

#include <QtCore/QCoreApplication>
#include <QTemporaryFile>
#include <QFileInfo>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTemporaryFile tempFile;

    if( tempFile.open() )
    {
        tempFile.write("This is a temporary file\n");
        tempFile.close();
    }

    QFileInfo info(tempFile);

    qDebug() << info.isFile();
    qDebug() << info.path();
    qDebug() << info.fileName();

    return a.exec();
}

 

3、QTextStream 与 QDataStream 

Qt中将文件类型分为2大类 

      - 文本文件 :文件内容是可读的文本字符 

      - 数据文件 :文件内容是直接的二进制数据 

QFile直接支持文本文件和数据文件的读写 

      - qint64 read(char* data, qint64 maxSize) 

      - QByteArray read(qint64 maxSize) 

      - qint64 write(const char* data, qint64 maxSize) 

      - qint64 write(const QByteArray& byteArray) 

#include <QtCore/QCoreApplication>
#include <QFile>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QFile file("C:/Users/wss/Desktop/test.hex");

    if( file.open(QIODevice::WriteOnly) ) // 没有指明文本类型,默认以二进制方式打开
    {
        QString dt = "QIODevice";
        double value = 3.14;

        file.write(dt.toStdString().c_str());
        file.write(reinterpret_cast<char*>(&value), sizeof(value));

        file.close();
    }

    if( file.open(QIODevice::ReadOnly) )
    {
        QString dt = "";
        double value = 0;

        dt = QString(file.read(9)); // 返回QByteArray对象
        file.read(reinterpret_cast<char*>(&value), sizeof(value));

        file.close();

        qDebug() << dt;
        qDebug() << value;
    }

    return a.exec();
}

文本流和数据流 

Qt提供辅助类简化了文本文件 / 数据文件的读写 

      - QTextStream :写入的数据全部转换为可读文本 

      - QDataStream :写入的数据根据类型转换为二进制数据 

#include <QtCore/QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QDebug>

void text_stream_test(QString f)
{
    QFile file(f);  // 创建IO设备对象

    if( file.open(QIODevice::WriteOnly | QIODevice::Text) ) // 文本,只写方式打开文件
    {
        QTextStream out(&file);   // 初始化文本流

        out << QString("QIODevice") << endl; 
        out << QString("Result: ") << endl;
        out << 5 << '*' << 6 << '=' << 5 * 6 << endl;

        file.close();
    }

    if( file.open(QIODevice::ReadOnly | QIODevice::Text) )
    {
        QTextStream in(&file);

        while( !in.atEnd() )
        {
            QString line = in.readLine();

            qDebug() << line;
        }

        file.close();
    }
}

void data_stream_test(QString f)
{
    QFile file(f);

    if( file.open(QIODevice::WriteOnly) )  
    {
        QDataStream out(&file);  // 初始化数据流

        out.setVersion(QDataStream::Qt_4_7);

        out << QString("QIODevice");
        out << QString("Result: ");
        out << 3.14;

        file.close();
    }

    if( file.open(QIODevice::ReadOnly) )
    {
        QDataStream in(&file);
        QString dt = "";
        QString result = "";
        double value = 0;

        in.setVersion(QDataStream::Qt_4_7);

        in >> dt;
        in >> result;
        in >> value;

        file.close();

        qDebug() << dt;
        qDebug() << result;
        qDebug() << value;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    text_stream_test("C:/Users/wss/Desktop/text.txt");
    data_stream_test("C:/Users/wss/Desktop/data.dat");
    
    return a.exec();
}

 

 

不同Qt版本的数据流文件格式可能不同 

  - void setVersion(int v)   // 设置读写版本号 

  - int version() const   // 获取读写版本号 

当数据流文件可能在不同版本的Qt程序间传递数据时,需要考虑版本问题! 

下面写了一个大致修复后缀名的代码,用到了数据流

由于word文档本质就是压缩为文档,所以会被解析为zip

void UpdateThread::fixFileSuffix(QString path)
{
    QDir dir(path);

    if(path == "" || !dir.exists())
        return;

    QFileInfoList subFileList = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::CaseSensitive);

    if(subFileList.empty())
        return;

    for (int i = 0; !m_stop && (i < subFileList.size()); i++)
    {
        if(subFileList[i].isDir())
        {
            fixFileSuffix(subFileList[i].absoluteFilePath());
        }
        else
        {
            QFile file(subFileList[i].absoluteFilePath());
            QString oldSuffix = subFileList[i].suffix();

            char buffer[8];
            memset(buffer, 0, sizeof (buffer));

            if(file.open(QIODevice::ReadOnly))
            {
                QDataStream in(&file);

                in.readRawData(buffer, sizeof(buffer));

                QByteArray ba(buffer, sizeof(buffer));

                //qDebug() << "ba : " << ba << endl;

                QByteArray two = ba.mid(0, 2).toHex().toUpper();
                QByteArray three = ba.mid(0, 3).toHex().toUpper();
                QByteArray four = ba.mid(0, 4).toHex().toUpper();
                QByteArray five = ba.mid(0, 5).toHex().toUpper();
                QByteArray lastFour = ba.mid(4, 4).toHex().toUpper();
                QByteArray seven = ba.mid(0, 7).toHex().toUpper();
                QByteArray eight = ba.toHex().toUpper();

                QString curDir = subFileList[i].absolutePath();
                QString baseName = subFileList[i].baseName();
                QString suffix = "";

                if(two == QByteArray("FFD8")) 
                    suffix = ".jpg";
                else if(three == QByteArray("494433") || three == QByteArray("FFFB50"))
                    suffix = ".mp3"; // 这些文件标识都是随便搜的,很多肯定有版本差异
                else if(three == QByteArray("89504E") || four == QByteArray("89504E47"))
                    suffix = ".png";
                else if(four == QByteArray("47494638"))
                    suffix = ".gif";
                else if(four == QByteArray("D0CF11E0") || four == QByteArray("0D444F43") ||
                        eight == QByteArray("31BE000000AB0000") || four == QByteArray("7FFE340A"))
                    suffix = ".doc";
                else if(four == QByteArray("504B0304") && (oldSuffix != "docx" && oldSuffix != "doc"))
                    suffix = ".zip";
                else if(four == QByteArray("52617221"))
                    suffix = ".rar";
                else if(four == QByteArray("57415645") || four == QByteArray("52494646"))
                    suffix = ".wav";
                else if(four == QByteArray("41564920"))
                    suffix = ".avi";
                else if(four == QByteArray("2E524D46 "))
                    suffix = ".rm";
                else if(four == QByteArray("000001BA")  || four == QByteArray("000001B3") )
                    suffix = ".mpg";
                else if(four == QByteArray("6D6F6F76") || four == QByteArray("6D646174"))
                    suffix = ".mov";
                else if(lastFour == QByteArray("66747970"))
                    suffix = ".mp4";
                else if(seven == QByteArray("255044462D312E") || four == QByteArray("25504446")
                        || three == QByteArray("255044"))
                    suffix = ".pdf";
                else if(two == QByteArray("FEFF") || two == QByteArray("FFFE") || three == QByteArray("EFBBBF"))
                    suffix = ".txt";
                else if(five == QByteArray("68746D6C3E"))
                    suffix = ".html";
                else if(five == QByteArray("3C3F786D6C"))
                    suffix = ".xml";
                else if(five == QByteArray("7B5C727466"))
                    suffix = ".rtf";
                else if(five == QByteArray("377ABCAF271C"))
                    suffix = ".7z";
                else if(four == QByteArray("464C5601"))
                    suffix = ".flv";
                else if(two == QByteArray("4D5A") && (oldSuffix != "dll" && oldSuffix != "com"))
                    suffix = ".exe";
                else if(three == QByteArray("00FFFF"))
                    suffix = ".img";
                else if(eight == QByteArray("64383A616E6E6F75"))
                    suffix = ".torrent";
                else
                    suffix = "";

                if(suffix != "" && !m_stop)
                    file.rename(curDir + "/" + baseName + suffix);

                file.close();
            }
        }

        if(!m_stop)
            emit updateUI(1);
    }
}

 

4、QBuffer

Qt中缓冲区的概念 

  -缓冲区的本质为一段连续的存储空间 ,QBuffer是Qt中缓冲区相关的类 

  -在Qt中可以将缓冲区看作一种特殊的IO设备 ,文件流辅助类可以直接用于操作缓冲区 

QBuffe缓冲区的使用场合 

  -在线程间进行不同类型的数据传递 

  -缓存外部设备中的数据返回 

  -数据读取速度小于数据写入速度 

#include <QtCore/QCoreApplication>
#include <QBuffer>
#include <QByteArray>
#include <QDataStream>
#include <QDebug>

void write_buffer(int type, QBuffer& buffer)
{
    if( buffer.open(QIODevice::WriteOnly) ) 
    {
        QDataStream out(&buffer); 

        out << type;

        if( type == 0 )
        {
            out << QString("PI");
            out << QString("3.1415");
        }
        else if( type == 1 )
        {
            out << 3;
            out << 1415;
        }
        else if( type == 2 )
        {
            out << 3.1415;
        }

        buffer.close(); //关闭IO设备
    }
}

void read_buffer(QBuffer& buffer)
{
    if( buffer.open(QIODevice::ReadOnly) )
    {
        int type = -1;
        QDataStream in(&buffer);

        in >> type;

        if( type == 0 )
        {
            QString dt = "";
            QString pi = "";

            in >> dt;
            in >> pi;

            qDebug() << dt;
            qDebug() << pi;
        }
        else if( type == 1 )
        {
            int a = 0;
            int b = 0;

            in >> a;
            in >> b;

            qDebug() << a;
            qDebug() << b;
        }
        else if( type == 2 )
        {
            double pi = 0;

            in >> pi;

            qDebug() << pi;
        }

        buffer.close();
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QByteArray array;   
    QBuffer buffer(&array); // 缓冲区对象关联到内存

    write_buffer(2, buffer); // 写缓冲区
    read_buffer(buffer);

    return a.exec();
}

 

 

5、QDir

QDir是Qt中功能强大的目录操作类

    -Qt中的目录分隔符统一使用 '/' 

    -QDir能够对目录进行任意操作(创建,删除,重命名) 

    -QDir能够获取指定目录中的所有条目(文件和文件夹) ,QDir能够使用过滤字符串获取指定条目 

    -QDir能够获取系统中的所有根目录 

#include <QtCore/QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QFileInfoList>
#include <QDebug>

void test_dir()
{
    const char* PATH = "C:/Users/wss/Desktop/QDir";
    QDir dir;

    if( !dir.exists(PATH) )
    {
        dir.mkdir(PATH);
    }

    if( dir.exists(PATH) )
    {
        dir.cd(PATH);

        QStringList list = dir.entryList();

        for(int i=0; i<list.count(); i++)
        {
            qDebug() << list[i];
        }
    }
}

unsigned int calculate_size(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 += calculate_size(list[i].absoluteFilePath());
            }
        }
    }

    return ret;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    test_dir();

    qDebug() << calculate_size("C:/Users/wss/Desktop/QDir");

    return a.exec();
}

 

6、文件系统监视器 

QFileSystemWatcher用于监控文件和目录的状态变化

      -能够监控特定目录和文件的状态 ,能够同时对多个目录和文件进行监控 

      -当目录或者文件发生改变时将触发信号 ,可以通过信号与槽的机制捕捉信号并做出响应 

Watcher.h

#ifndef _WATCHER_H_
#define _WATCHER_H_

#include <QObject>
#include <QFileSystemWatcher>

class Watcher : public QObject
{
    Q_OBJECT

    QFileSystemWatcher m_watcher;
private slots:
    void statusChanged(const QString& path);//参数可以查阅Qt帮助
public:
    explicit Watcher(QObject *parent = 0);
    void addPath(QString path);
};

#endif // WATCHER_H

Watcher.cpp

#include "Watcher.h"
#include <QDebug>

Watcher::Watcher(QObject *parent) : QObject(parent)
{
    connect(&m_watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(statusChanged(const QString&)));
    connect(&m_watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(statusChanged(const QString&)));
}

void Watcher::statusChanged(const QString &path)
{
    qDebug() << path << "is changed!";
}

void Watcher::addPath(QString path)
{
    m_watcher.addPath(path);
}

main.cpp

#include <QtCore/QCoreApplication>
#include "Watcher.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Watcher watcher;

    watcher.addPath("C:/Users/wss/Desktop/text.txt");
    watcher.addPath("C:/Users/wss/Desktop/QDir");
    
    return a.exec();
}

 

 

 

 

  • 12
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值