Qt浅谈之十四:文件操作

一、简介

       通过QFile、QDir、QFileInfo和QFileSystemWatcher类简单介绍对文件和目录的一些操作。对文本流和数据流没有太多的介绍,还有一些Qt资源、统一资源定位符、缓冲区可以在以后应用中加上。

二、详解

1、QFile

可以读写文本文件、二进制文件和Qt资源文件,也可以和QTextStream和QDataStream一起使用。

(1)读写文本文件

	QFile file(fileName);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
		return -1;
	}

	while (!file.atEnd()) {
		QByteArray line = file.readLine();
		for (int i = 0; i < line.size(); ++i)
			cout << line[i];	
	}
	file.seek(0);      //回到文件开头
	QTextStream in(&file);
	while (!in.atEnd()) {
		QString line = in.readLine();
		cout << qPrintable(line) << endl;
	}

{
        QFile file("logfile.log");
        file.open(QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text);
        QTextStream out(&file);
        out << QString("log11111") << endl;
        file.close();
}

(2)读写二进制文件

        QFile file("binary.file");
	file.open(QIODevice::WriteOnly | QIODevice::Truncate);
	QDataStream out(&file);   
	out << QString("caizhiming");   
	out << QDate::fromString("1986/01/03", "yyyy/MM/dd");
	out << (qint32)21;
	file.close();

	file.setFileName("binary.file");
	if(!file.open(QIODevice::ReadOnly)) {
		return -1;
	}
	QDataStream in(&file);
	QString name;
	QDate birthday;
	qint32 age;
	in >> name >> birthday >> age;
	qDebug() << name << birthday << age;
 	cout << qPrintable(name) << '\t' << qPrintable(birthday.toString("yyyy MMMM dd dddd")) << "\t" << age << endl;
	file.close();

2、QDir

       QDir可以操作目录,存取目录或文件信息,操作底层文件系统,而且还可以存取Qt的资源文件。Qt使用/作为通用的目录分割符和URL路径分隔符,Qt会自动地转换你的路径来匹配你的基础的操作系统。Qt可以使用相对路径和绝对路径指向一个文件,isRelative()和 isAbsolute()函数可以判断QDir对象使用的是相对路径还是绝对路径。将相对路径转换为绝对路径使用makeAbsolute()函数。目录 路径可以通过path()函数返回,通过setPath()函数设置新路径,绝对路径使用absolutePath()返回。目录名可以使用 dirName()返回。目录的路径可以通过cd()、cdUp()改变,可以使mkdir()创建目录,rename()改变目录名。判断目录是否存在可以使用exists(),目录的属性可以使用 isReadable(),isAbsolute(),isRelative()和isRoot()来获取,目录下有很多条目,包括文件、目录和符号链 接,总的条目数可以使用count()来统计。entryList()可以返回目录下所有条目组成的字符串链表,文件可以使用remove()函数删 除,rmdir()删除目录。

(1) 绝对路径的用法:
QDir("/home/user/Documents")
QDir("C:/Documents and Settings")或使用QDir("C:\\Documents and Settings")来代替

相对路径的用法:
QDir("images/landscape.png")

(2) QDir mDir("/home/user/Desktop");

mDir.exists(); //测试文件是否存在

mDir.absoluteFilePath("main.cpp"); //返回指定目录下指定文件的绝对路径

mDir.dirName(); //剥离掉路径,只返回目录的名字

其他的可以参看QT文档。

3、QFileInfo

       QFileInfo类提供了与系统无关的文件信息,它能提供文件名称和路径,存取权限,以及文件是否为目录或符号链接,文件大小,以 及最后修改/读取的时间等。QFileInfo也能从资源中获取信息。QFileInfo可以使用相对路径或绝对路径。

(1)文件属性信息

    QFileInfo info("/home/aoyang/network-manager-applet.tar.gz");
    bool isExists = info.exists();          //判断文件是否存在,若存在返回true
    qint64 size = info.size();              //获取文件大小,返回bytes
    QDateTime created = info.created();     //文件创建时间
    QDateTime lastModified = info.lastModified();  //文件最近修改时间
    QDateTime lastRead = info.lastRead();  //文件最近读取时间
    bool isDir = info.isDir();             //判断是否是路径
    bool isFile = info.isFile();           //判断是否是文件
    bool isSymLink = info.isSymLink();     //判断是否是符号链接
    bool isHidden = info.isHidden();       //文件是否隐藏
    bool isReadable = info.isReadable();   //文件是否可读
    bool isWritable = info.isWritable();   //文件是否可写
    bool isExecutable =info.isExecutable(); //文件是否可执行

(2)文件路径信息

    QString absolutefilepath = info.absoluteFilePath(); //绝对文件路径:/home/aoyang/network-manager-applet.tar.gz
    QString absolutepath = info.absolutePath();         //绝对路径不包含文件名:/home/aoyang
    QString basename = info.baseName();                 //无路径并第一个.前的名称:network-manager-applet
    QString completebasename = info.completeBaseName(); //最后一个.前的名称:network-manager-applet.tar
    QString completesuffix = info.completeSuffix();     //第一个.后的后缀:tar.gz
    QString filename = info.fileName();                 //文件全名称:network-manager-applet.tar.gz
    QString filepath = info.filePath();                 //文件路径全名称:/home/aoyang/network-manager-applet.tar.gz
    QString path = info.path();                         //文件路径:/home/aoyang
    QString suffix = info.suffix();                     //文件后缀:gz
Qt浅谈之十四:文件操作_第1张图片

4、QFileSystemWatcher文件系统监视器

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileSystemWatcher>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void showMessage(const QString &path);

private:
    Ui::MainWindow *ui;
    QFileSystemWatcher myWatcher;
};

#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDir>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 将监视器的信号和自定义的槽进行关联
    connect(&myWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(showMessage(QString)));
    connect(&myWatcher, SIGNAL(fileChanged(QString)), this, SLOT(showMessage(QString)));

    // 显示出当前目录下的所有.h文件
    QDir myDir(QDir::currentPath());
    myDir.setNameFilters(QStringList("*.h"));
    ui->listWidget->addItem(myDir.absolutePath() + tr("目录下的.h文件有:"));
    ui->listWidget->addItems(myDir.entryList());

    // 创建目录,并将其加入到监视器中
    myDir.mkdir("mydir");
    myDir.cd("mydir");
    ui->listWidget->addItem(tr("监视的目录:") + myDir.absolutePath());
    myWatcher.addPath(myDir.absolutePath());
    // 创建文件,并将其加入到监视器中
    QFile file(myDir.absolutePath() + "/myfile.txt");
    if (file.open(QIODevice::WriteOnly)) {
        QFileInfo info(file);
        ui->listWidget->addItem(tr("监视的文件:") + info.absoluteFilePath());
        myWatcher.addPath(info.absoluteFilePath());
        file.close();
    }
}

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

// 显示文件或目录改变信息
void MainWindow::showMessage(const QString &path)
{
    QDir dir(QDir::currentPath() + "/mydir");
    // 如果是目录发生了改变
    if (path == dir.absolutePath()) {
        ui->listWidget->addItem(dir.dirName() + tr("目录发生改变: "));
        ui->listWidget->addItems(dir.entryList());
    } else { // 如果是文件发生了改变
        ui->listWidget->addItem(path + tr("文件发生改变!"));
    }
}
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created: Wed Jul 30 17:53:29 2014
**      by: Qt User Interface Compiler version 4.6.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHeaderView>
#include <QtGui/QListWidget>
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWidget>

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
    QWidget *centralWidget;
    QVBoxLayout *verticalLayout;
    QListWidget *listWidget;
    QMenuBar *menuBar;
    QToolBar *mainToolBar;
    QStatusBar *statusBar;

    void setupUi(QMainWindow *MainWindow)
    {
        if (MainWindow->objectName().isEmpty())
            MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
        MainWindow->resize(400, 300);
        centralWidget = new QWidget(MainWindow);
        centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
        verticalLayout = new QVBoxLayout(centralWidget);
        verticalLayout->setSpacing(6);
        verticalLayout->setContentsMargins(11, 11, 11, 11);
        verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
        listWidget = new QListWidget(centralWidget);
        listWidget->setObjectName(QString::fromUtf8("listWidget"));

        verticalLayout->addWidget(listWidget);

        MainWindow->setCentralWidget(centralWidget);
        menuBar = new QMenuBar(MainWindow);
        menuBar->setObjectName(QString::fromUtf8("menuBar"));
        menuBar->setGeometry(QRect(0, 0, 400, 25));
        MainWindow->setMenuBar(menuBar);
        mainToolBar = new QToolBar(MainWindow);
        mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
        MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
        statusBar = new QStatusBar(MainWindow);
        statusBar->setObjectName(QString::fromUtf8("statusBar"));
        MainWindow->setStatusBar(statusBar);

        retranslateUi(MainWindow);

        QMetaObject::connectSlotsByName(MainWindow);
    } // setupUi

    void retranslateUi(QMainWindow *MainWindow)
    {
        MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0, QApplication::UnicodeUTF8));
    } // retranslateUi

};

namespace Ui {
    class MainWindow: public Ui_MainWindow {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_MAINWINDOW_H


       目录的改变和文件的改变都能监视到,文件改变会收到一次信号,但是文件改变目录发出了很多次变化,其中除了临时文件的创建和删除,还有两次不知道为什么会收到信号,这个等有机会在了解。

四、总结

(1)只是总结了常用的部分,其他的使用时可以直接参看Qt的参考文档,Qt4.3又加入了许多比较新的特性。

(2)本人思路有限,若有更好的建议,也可发邮件沟通,在此先感谢!邮箱地址[email protected]


你可能感兴趣的:(Qt浅谈之十四:文件操作)