文件与流
目录
QFile、QFileDialog、QFileInfo
在Qt框架中,QFile
、QFileDialog
和 QFileInfo
是与文件处理相关的类,它们各自承担不同的角色:
QFile
QFile
是用于文件操作的类,它提供了读取、写入和处理文件的基本功能。QFile
可以打开文件,检查文件是否存在,以及执行其他文件相关的操作。以下是 QFile
的一些常用功能:
-
打开文件:使用
open()
方法以特定的模式(如只读、只写、追加等)打开文件。 -
读取和写入:使用
read()
、readLine()
、readAll()
等方法读取文件内容,使用write()
方法写入数据到文件。 -
文件属性:可以检查文件是否存在、是否可读、是否可写等属性。
-
文件位置:使用
seek()
方法移动文件读写位置。 -
关闭文件:使用
close()
方法关闭文件。
文件名通常在构造函数中传递,但可以随时使用setFileName()
设置。QFile要求文件分隔符为“/”,而不管操作系统如何。不支持使用其他分隔符(例如“\”),可使用 “ \\ ”。 您可以使用exists()
检查文件是否存在,并使用remove()
删除文件。(QFileInfo
和QDir
提供了更高级的文件系统相关操作。)文件用open()
打开,用close(
)关闭,用flush()
刷新。通常使用QDataStream
或QTextStream
读取和写入数据,但您也可以调用QIODevice
继承的函数read()、readLine()、readAll()、write()
。QFile还继承了getChar()、putChar()和ungetChar()
,它们一次只能处理一个字符。 文件的大小由size()
返回。您可以使用pos()
获取当前文件位置,或使用seek()
移动到新的文件位置。如果你已经到达文件的末尾,atEnd()
返回true
。
直接读取文件:
QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!file.atEnd()) {
QByteArray line = file.readLine();
process_line(line);
}
使用流读取文件:
QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
process_line(line);
}
QFile file("out.txt");
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return;
QTextStream out(&file);
out << "The magic number is: " << 49 << "\n";
要编写文本,我们可以使用运算符<<(),它被重载以在左侧获取QTextStream,在右侧获取各种数据类型(QString),QDataStream与此类似,您可以使用运算符<<()写入数据,使用运算符>>()读回数据。
QFileDialog
QFileDialog
是一个用于创建文件选择对话框的类。它允许用户在图形界面中选择文件或目录。QFileDialog
可以用于打开文件、保存文件或选择目录。以下是 QFileDialog
的一些常用功能:
-
打开文件:使用
getOpenFileName()
或getOpenFileUrl()
方法显示一个对话框,让用户选择一个或多个文件。 -
保存文件:使用
getSaveFileName()
或getSaveFileUrl()
方法显示一个对话框,让用户选择保存文件的位置和文件名。 -
选择目录:使用
getExistingDirectory()
方法让用户选择一个目录。
QFileInfo
QFileInfo
提供了关于文件、目录和链接等文件系统对象的信息。它可以用来获取文件的大小、权限、创建和修改时间等属性。以下是 QFileInfo
的一些常用功能:
-
获取文件信息:通过构造函数传入文件路径来创建
QFileInfo
对象。 -
文件属性:使用
size()
、isDir()
、isFile()
、isReadable()
等方法获取文件的属性。 -
文件路径:使用
filePath()
、absolutePath()
、canonicalPath()
等方法获取文件的路径信息。 -
修改时间:使用
lastModified()
方法获取文件的最后修改时间。
// 使用QFileInfo获取文件信息
QFileInfo fileInfo("example.txt");
if (fileInfo.isFile()) {
qDebug() << "File size:" << fileInfo.size();
qDebug() << "Last modified:" << fileInfo.lastModified();
}
案例
#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
#include <QDateTime>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->pushButton, &QPushButton::clicked, [&](){
QString filename = QFileDialog::getOpenFileName(this, "打开文件", "C:\\Users\\jackb");
ui->lineEdit->setText(filename);
QFile file(filename);
file.open(QIODevice::ReadOnly);
//QByteArray array = file.readAll();
QByteArray array;
while(!file.atEnd())
{
array += file.readLine();
}
ui->textEdit->setText(array);
file.close();
file.open(QIODevice::Append);
file.write("I love you, Rick!");
file.close();
});
QFile file("C:\\Users\\jackb\\MyText.txt");
QFileInfo info(file);
qDebug() << "绝对路径:" << info.absoluteFilePath();
qDebug() << "文件名:" << info.fileName();
qDebug() << "后缀名:" << info.suffix();
//qDebug() << "创建时间:" << info.created();
qDebug() << "创建时间:" << info.created().toString("yyyy.MM.dd hh:mm:ss");
qDebug() << "文件大小:" << info.size();
file.open(QIODevice::ReadOnly);
file.seek(0);
QByteArray array = file.read(5);
qDebug() << "前5个字节: " << array;
qDebug() << "当前位置: " << file.pos();
file.seek(15);
array = file.read(5);
qDebug() << "第16到第20个字节: " << array;
file.close();
}
Widget::~Widget()
{
delete ui;
}
QDir
QDir
是 Qt 框架中的一个类,它提供了对文件系统目录的抽象表示,允许你以一种与操作系统无关的方式进行目录操作。QDir
可以用于创建、删除、重命名目录,以及列出目录中的文件和子目录。
以下是 QDir
类的一些常用功能:
-
目录路径:
-
使用
QDir::setCurrent()
设置当前工作目录。 -
使用
QDir::currentPath()
获取当前工作目录的路径。
-
-
目录创建和删除:
-
使用
mkdir()
创建新目录。 -
使用
rmdir()
删除空目录。
-
-
目录列表:
-
使用
entryList()
或entryInfoList()
获取目录中的文件和子目录列表。这两个方法都允许你指定过滤条件,比如只列出文件或只列出符合特定模式的文件。
-
-
目录遍历:
-
使用
cd()
方法改变当前目录,并使用cdUp()
返回上一级目录。
-
-
目录属性:
-
使用
exists()
检查目录是否存在。 -
使用
isReadable()
、isWritable()
等方法检查目录的可读性和可写性。
-
-
文件过滤:
-
使用
setNameFilters()
设置文件名过滤器,以过滤出符合特定模式的文件。
-
-
文件排序:
-
使用
setSorting()
设置文件和目录的排序方式,例如按名称、大小或修改时间排序。
-
-
绝对路径和相对路径:
-
使用
absolutePath()
获取目录的绝对路径。 -
使用
relativePath()
获取相对于另一个目录的相对路径。
-
示例代码
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFileSystemWatcher>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
QFileSystemWatcher myWatcher;//文件监视器
private slots:
void showMessage(const QString &path);
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QDir>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//QDir myDir(QDir::currentPath());
//qDebug() << myDir;
QDir myDir("C:\\Users");
ui->listWidget->addItem(myDir.absolutePath());
ui->listWidget->addItems(myDir.entryList());
myDir.setNameFilters(QStringList("*.cpp"));//过滤
ui->listWidget->addItems(myDir.entryList());
//文件监视
myDir.mkdir("mydir");
connect(&myWatcher, &QFileSystemWatcher::directoryChanged, this, &Widget::showMessage);
connect(&myWatcher, &QFileSystemWatcher::fileChanged, this, &Widget::showMessage);
myWatcher.addPath("C:\\Users\\jackb\\mydir");
myWatcher.addPath("C:\\Users\\jackb\\MyText.txt");
}
Widget::~Widget()
{
delete ui;
}
void Widget::showMessage(const QString &path)
{
if(path == "C:\\Users\\jackb\\mydir")
ui->listWidget->addItem("C:\\Users\\jackb\\mydir 目录发生改变");
else
ui->listWidget->addItem("C:\\Users\\jackb\\MyText.txt 文件发生改变");
}
文本流与数据流
在Qt中,流(Streams)是一种用于处理数据输入输出的机制,类似于C++标准库中的流(如std::iostream
)。Qt提供了几种不同类型的流,主要用于处理文本和二进制数据的读写操作。以下是一些主要的Qt流类及其用途:
-
QTextStream:
-
用于处理文本数据的输入输出。
-
可以与标准输入输出流(如
cin
、cout
)或文件流(如QFile
)一起使用。 -
支持格式化输入输出,类似于C语言的
printf
和scanf
。
-
-
QDataStream:
-
用于处理二进制数据的输入输出。
-
可以与任何二进制设备一起使用,如文件、网络套接字等。
-
支持数据的序列化和反序列化,即对象的读写操作。
-
-
QFile:
-
用于文件操作,如打开、关闭、读取和写入文件。
-
可以与
QTextStream
或QDataStream
一起使用,实现文本或二进制数据的读写。
-
-
QIODevice:
-
是所有I/O设备的基类,提供了一些基本的I/O操作,如
read()
、write()
和seek()
。 -
包括
QFile
、QTcpSocket
、QProcess
等。
-
-
QBuffer:
-
用于将数据存储在内存中,而不是文件或设备中。
-
可以与
QTextStream
或QDataStream
一起使用,实现内存中的数据读写。
-
-
QProcess:
-
用于执行外部程序并与之通信。
-
可以读取和写入外部程序的标准输入输出流。
-
-
QTcpSocket 和 QUdpSocket:
-
用于网络通信,分别实现TCP和UDP协议。
-
可以与
QDataStream
一起使用,实现网络数据的读写。
-
-
QXmlStreamReader 和 QXmlStreamWriter:
-
用于处理XML数据的输入输出。
-
可以解析XML文档或生成XML格式的数据。
-
使用示例
以下是一些使用Qt流的基本示例:
QTextStream 示例
QFile file("example.txt");
if (file.open(QIODevice::ReadOnly)) {
QTextStream in(&file);
QString line;
while (!in.atEnd()) {
line = in.readLine();
qDebug() << line;
}
file.close();
}
QDataStream 示例
QFile file("data.bin");
if (file.open(QIODevice::ReadWrite)) {
QDataStream out(&file);
out << 42 << "Hello, Qt!";
file.close();
}
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
QDataStream stream(&buffer);
stream << "Hello, Qt!";
buffer.seek(0);
QByteArray data = buffer.readAll();
qDebug() << data;