QT五 文件系统,QFile,QfileInfo
总览
- QIODevice:所有 I/O 设备类的父类,提供了字节块读写的通用操作以及基本接口;
- QFileDevice:Qt5新增加的类,提供了有关文件操作的通用实现。
- QFlie:访问本地文件或者嵌入资源;
- QTemporaryFile:创建和访问本地文件系统的临时文件;
- QBuffer:读写QbyteArray, 内存文件;
- QProcess:运行外部程序,处理进程间通讯;
- QAbstractSocket:所有套接字类的父类;
- QTcpSocket:TCP协议网络数据传输;
- QUdpSocket:传输 UDP 报文;
- QSslSocket:使用 SSL/TLS 传输数据;
文件系统分类:
1. 顺序访问设备:
是指它们的数据只能访问一遍:从头走到尾,从第一个字节开始访问,直到最后一个字节,中途不能返回去读取上一个字节,这其中,QProcess、QTcpSocket、QUdpSoctet和QSslSocket是顺序访问设备。
2. 随机访问设备:
可以访问任意位置任意次数,还可以使用QIODevice::seek()函数来重新定位文件访问位置指针,QFile、QTemporaryFile和QBuffer是随机访问设备,
核心 QFlie-基本文件操作
QFile提供了从文件中读取和写入数据的能力。
我们通常会将文件路径作为参数传给QFile的构造函数。不过也可以在创建好对象最后,使用setFileName()来修改。
打开文件普通文件,关闭文件,读取文件
读取UTF-8格式的文件的三种方式
void MainWidget::on_openbutton_clicked()
{
qDebug()<<"openclick";
//通过dialogfile,让user选择一个txt文件。
QFileDialog filedialog;
QString openfilename = filedialog.getOpenFileName(this,"选择你要打开的文件","../","Text files (*.txt);;XML files (*.xml)");
//如果user没有选择,则返回null
if(nullptr==openfilename){
qDebug()<<"openfilename = null";
return;
}else{
qDebug()<<openfilename.toUtf8().data();
}
//走到这里说明该文件的存在的,使用文件名 构建一个QFile
QFile file(openfilename);
char data[1024] = {0};
int readlen = 0;
bool openok = file.open(QIODevice::ReadOnly);
if(false == openok){
qDebug()<<"file open error";
}else{
qDebug()<<"file open success";
//方式一,QFile提供了 readAll()函数,一次性读完
//这里要读取的是utf-8的文本文件,如果不是utf-8格式,则显示的是乱码
// QByteArray bytearr = file.readAll();
// ui->textEdit->setText(bytearr);
//方式二 按照C++的语法写。QFile read函数的返回值如下:如果读取到的值是0,说明读到文件末尾了,如果是-1说明有error发生,如果大于0,才是真的有数据
// while((readlen = file.read(data,1024)) != 0){
// if(readlen==-1){
// ui->textEdit->setText("读取文件发生问题\n");
// break;
// }else if(readlen > 0 ){
// ui->textEdit->append(data);
// }
// }
//方式三。
QByteArray ba ;
while(!file.atEnd()){
// qDebug()<<file.readLine(); readline 函数的内部实现是读完一行就继续下一行,知道结束,我们这里如果这样打log,那么再次调用readline就会读取下一行
ba.append(file.readLine());
}
ui->textEdit->setText(ba);
}
file.close();
}
读取其他文件格式的文件 -参见 QTextStream
存储文件
void MainWidget::on_savebutton_clicked()
{
qDebug()<<"saveclick";
QFileDialog filedialog;
QString savefilename = filedialog.getSaveFileName(this,"save","../","Text files (*.txt)");
if(savefilename.isEmpty() == false){
qDebug()<<"保存的文件名为" <<savefilename;
QFile file(savefilename);
bool saveok = file.open(QIODevice::WriteOnly);
if(saveok ==false){
qDebug()<<"打开文件失败"<< file.fileName();
return;
} else {
QString qs = this->ui->textEdit->toPlainText();
file.write(qs.toUtf8());
}
file.close();
}else{
qDebug()<<"用户取消了保存";
return;
}
}
使用 QDataStream 打开二进制文件
注意的是,我们保存的是二进制的文件,即使名字是.txt,使用txt也是打不开的。
void MainWidget::savedata(){
QFile qfile("../resource/009qfile/savedata.txt");
bool wirteok = qfile.open(QIODevice::WriteOnly);
if(wirteok==false){
qDebug()<<"文件不存在";
return;
}else{
qDebug()<<"savedata.txt存在";
QDataStream datastream(&qfile);
datastream<<QString("中国")<< 123567;
}
qfile.close();
}
打开二进制文件
void MainWidget::readdata(){
QFile qfile("../resource/009qfile/savedata.txt");
bool readok = qfile.open(QIODevice::ReadOnly);
if(readok==false){
qDebug()<<"读取文件不存在";
return;
}else{
qDebug()<<"读取文件savedata.txt存在";
QDataStream datastream(&qfile);
QString wenzi;
int a;
datastream>>wenzi >> a;
qDebug()<<wenzi;
qDebug()<<wenzi.toUtf8().data();
qDebug()<<a;
}
qfile.close();
}
使用 QTextStream使用指定编码
这里要注意的是:你存储的时候用的什么编码,读取的时候也要用什么编码。
如果我们打开的文件不知道是什么编码,那是无法打开的。
void MainWidget::saveTextStream(){
QFile qfile("../resource/009qfile/saveTextStream.txt");
bool wirteok = qfile.open(QIODevice::WriteOnly);
if(wirteok==false){
qDebug()<<"saveTextStream.xt文件不存在";
return;
}else{
qDebug()<<"saveTextStream.txt存在";
QTextStream textstream(&qfile);
textstream.setCodec("UTF-16");
textstream<<QString("中国人zhongguo")<< 123567;
}
qfile.close();
}
void MainWidget::readTextStream(){
qDebug()<<"openclick";
//通过dialogfile,让user选择一个txt文件。
QFileDialog filedialog;
QString openfilename = filedialog.getOpenFileName(this,"选择你要打开的文件","../","Text files (*.txt);;XML files (*.xml)");
//如果user没有选择,则返回null
if(nullptr==openfilename){
qDebug()<<"openfilename = null";
return;
}else{
qDebug()<<openfilename.toUtf8().data();
}
//走到这里说明该文件的存在的,使用文件名 构建一个QFile
QFile file(openfilename);
bool openok = file.open(QIODevice::ReadOnly);
if(false == openok){
qDebug()<<"file open error";
}else{
//注意这里的读取方式
qDebug()<<"file open success";
QTextStream textstream(&file);
textstream.setCodec("UTF-16");
ui->textEdit->setText(textstream.readAll());
}
file.close();
}
QFileInfo
有关文件本身的信息,比如文件名、文件所在目录的名字等,则是通过QFileInfo获取
//走到这里说明该文件的存在的,使用文件名 构建一个QFile
QFile file(openfilename);
//值得注意的是,有关文件本身的信息,比如文件名、文件所在目录的名字等,则是通过 QFileInfo 获取,而不是自己分析文件路径字符串。
QFileInfo info(file);
qDebug() << "info.isDir()" << info.isDir();//info 是不是路径
qDebug() << "info.isSymLink()" << info.isSymLink();//如果此对象指向符号链接或快捷方式,则返回true;否则返回false。
qDebug() << "info.isFile()" << info.isFile();// 是不是文件
qDebug() << "info.isExecutable()" << info.isExecutable(); //是不是可执行文件,对于windows,指的应该就是exe文件
qDebug() << "info.baseName()" << info.baseName(); // QFileInfo fi("/tmp/archive.tar.gz"); QString base = fi.baseName(); // base = "archive"
qDebug() << "info.completeBaseName() " << info.completeBaseName();// QFileInfo fi("/tmp/archive.tar.gz"); QString base = fi.completeBaseName(); // base = "archive.tar"
qDebug() << "info.suffix()" << info.suffix();
qDebug() << "info.completeSuffix()" << info.completeSuffix();//和suffix的区别在 QFileInfo fi("/tmp/archive.tar.gz");QString ext = fi.completeSuffix(); // ext = "tar.gz" //如果是suffix(),则结果是gz
qDebug()<<fileinfo.created().time().hour();
qDebug()<< fileinfo.created().toString("dd-MM-yyyy hh:mm:ss ap");
//结果
//D:/code_qt/resource/009qfile/你好utf-8.txt
//info.isDir() false
//info.isSymLink() false
//info.isFile() true
//info.isExecutable() false
//info.baseName() "你好utf-8"
//info.completeBaseName() "你好utf-8"
//info.suffix() "txt"
//info.completeSuffix() "txt"
//15
//"30-03-2025 03:04:14 下午"