qt – 文件
qt-文件操作
文件读写、创建、删除、重命名、拷贝
可操作:文本文件、二进制文件
文件对话框
#include <QFileDialog>
#include <QString>
#include <QDebug>
/*
静态数据成员:
类的一部分,为类的所有实例共享,处在静态区
类名::静态成员访问
非静态数据成员:
实例的一部分,类的每个实例都有一份拷贝,处在动态区
静态函数成员与非静态函数成员,都为类所有,实例对象不存在函数的拷贝
静态函数成员:
类名::方法 或者 实例对象.方法
编译器不向函数传递this指针,不识别实例对象个体,经常用来操作静态数据成员(要访问类的非静态成员可以通过对象来实现)
非静态函数成员:
实例对象.方法 或者 实例对象->方法
调用时编译器向函数传递this指针
*/
// 使用静态成员函数的方法调用
QString filename=QFileDialog::getOpenFileName(this,
"open file",
"f:\\",
tr("images(*.png *.jpg)")); // tr是字体兼容性的问题
qDebug()<<filename;
字体对话框
#include <QFontDialog>
#include <QString>
#include <QDebug>
bool ok; // 标志是否选择一个字体
QFont font=QFontDialog::getFont(&ok,this); // 返回一个字体
if (ok)
{
ui->FontButton->setFont(font);
}
else
{
qDebug()<<"not font be choiced!";
}
输入对话框 – 字符串\数字
void MainWindow::on_InputButton_clicked()
{
bool flag; // 是否有输入
// QLineEdit:: 显示的模式 // 关键参数是LineEdit::Normal lineEidt::password
// password 默认提示字符
QString input=QInputDialog::getText(this,"输入对话框","请输入用户名",QLineEdit::Normal,"password",&flag);
if (flag)
{
qDebug()<<input;
}
bool flag_val;
int val=QInputDialog::getInt(this,"输入对话框","0-100",0,0,256,1,&flag_val);
if (flag)
{
qDebug()<<val;
}
}
QMessageBox 消息对话框
// 问题对话框
int ret=QMessageBox::question(this,
"question", // 对话框的标题
"ues Qt T or F", // 对话框的内容
QMessageBox::Yes, // 可选择的模式
QMessageBox::No);
if (ret==QMessageBox::yes)
{
qDebug()<<"yes";
}
// 提示对话框
QMessageBox::information(this,
"notice",
"best to ues qt",
QMessageBox::Ok);
//警告对话框
QMessageBox::warning(this,
"warning",
"warning...",
QMessageBox::Ok);
// 关于对话框...
进度对话框
#include <QProgressBox>
// 静态成员函数 可以利用 类名::静态成员函数
// 非静态成员函数 可以利用 类名 对象的方式创建
/*
静态数据成员:
类的一部分,为类的所有实例共享,处在静态区
类名::静态成员访问
非静态数据成员:
实例的一部分,类的每个实例都有一份拷贝,处在动态区
静态函数成员与非静态函数成员,都为类所有,实例对象不存在函数的拷贝
静态函数成员:
类名::方法 或者 实例对象.方法
编译器不向函数传递this指针,不识别实例对象个体,经常用来操作静态数据成员(要访问类的非静态成员可以通过对象来实现)
非静态函数成员:
实例对象.方法 或者 实例对象->方法
调用时编译器向函数传递this指针
*/
// 该类没有静态成员函数,所以只能通过创建对象来实现
// 堆中 全局,不释放
// 由于没有delete 加上对象树的概念,会一直消耗内存
// QProgressDialog *prodlg=new QProgressDialog(this);
// 栈中 局部,释放
QProgressDialog prodlg("copy progress",
"stop",
0,
50000,
this);
// 设置模态
prodlg.setWindowModality(Qt::WindowModal);
prodlg.setWindowTitle("copy file");
prodlg.show();
for (int i=0;i<50000;i++)
{
prodlg.setValue(i);
// 类似并发 多线程 强制每隔一段时间还有没有其他时间没做完
// copy的同时 检测还有没有其他的事情要做
QCoreApplication::processEvents();
if (prodlg.wasCanceled()) // 当点击取消的时候
{
qDebug()<<"stop copy...";
// break;
return ;
}
prodlg.setValue(50000);
}
qDebug()<<"copy done...";
文本文件
#include <QApplication>
#include <QDebug>
#include <QFile>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 创建QFile对象,同时指定要操作的文件
// 注意这个文件(在使用相对路径的时候)会与可执行文件exe处于同一个路径文件夹下
QFile file("./demo.txt");
if (!file.open(QIODevice::WriteOnly|QIODevice::Text)){
qDebug()<<"文件打开失败"; // 相当于cout,qDebug还有更高级的用法
}
// 向文件中写入字符串
file.write("ex\n");
file.write("ex2\n");
//关闭文件
file.close();
//重新打开文件,对文件进行读操作
if (!file.open(QIODevice::ReadOnly|QIODevice::Text)){
qDebug()<<"文件打开失败";
}
// 每次都读取一行
// 创建一个字符串(字符串数组)
char* str=new char[100];
// 每次从文件中读取一行数据或读取最多maxSize-1个字节,存储到data中
// 返回读取到的字节数
qint64 readNum=file.readLine(str,100);
// 当读取出现错误 (返回为-1)或者读取到字符数为0时,结束读取
while ((readNum!=0)&&(readNum!=-1)){
qDebug()<<str;
readNum=file.readLine(str,100); // 会覆盖
}
file.close();
return 0;
}
二进制文件
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 指定要写入文件的数据
qint32 nums[5]={1,2,3,4,5};
// 写入文件之前,将数据转换成字节数组
QByteArray byteArr;
byteArr .resize(sizeof(nums));
for (int i=0;i<5;i++){
// 借助指针,将每个整数拷贝到字节数组中
memcpy(byteArr.data()+i*sizeof(qint32),&(nums[i]),sizeof(qint32));
}
// 将byteArr 字节数组存储到文件中
QFile file("./demo_byte.dat");
file.open(QIODevice::WriteOnly);
file.write(byteArr);
file.close();
// 再次打开文件,读取二进制数据
file.open(QIODevice::ReadOnly);
QByteArray resArr=file.readAll();
qDebug()<<"resArr:"<<resArr;
//将二进制转换为整数
char* data=resArr.data();
while(*data){
qDebug()<<*(qint32*)data;
data+=sizeof(qint32);
}
return 0;
}
文件操作实例
#include <QFileDialog>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
/* 文件读写 */
QString fileName=QFileDialog::getOpenFileName(this,"打开文件","./"); // 可以是相对路径
// 显示文件名
ui->lineEdit->setText(fileName);
//打开文件
QFile file(fileName);
file.open(QIODevice::ReadOnly); // 只读方式
// 读取全部内容
QByteArray array=file.readAll(); // read(size)读取指定个字节大小
ui->textEdit->setText(array); // QByteArray -> QString 隐式转换
// 判断是否到文件末尾
ui->textEdit->clear();
file.seek(0);
while (!file.atEnd())
{
QByteArray lineArray=file.readLine();
ui->textEdit->append(lineArray);
}
file.close();
file.open(QIODevice::Append);
file.write("\nhello vs\n"); // 这种才是正确的写法
file.write("hello vs code\n");
file.close();
/* 文件属性 */
QFile file2("./test.txt");
QFileInfo file2_info(file2); // 文件信息
qDebug()<<file2_info.absoluteFilePath(); // 文件绝对路径
qDebug()<<file2_info.fileName();
qDebug()<<file2_info.suffix(); // 后缀名
#if QT_VERSION>0x060000
qDebug()<<file2_info.birthTime().date();
qDebug()<<file2_info.birthTime().time();
qDebug()<<file2_info.birthTime().toString("yyyy.MM.dd hh::mm::ss");
#else
qDebug()<<file2_info.created();
#endif
/* 文件定位 */
file2.open(QIODevice::ReadOnly);
file2.seek(0); // 文件指针指向开头的位置
QByteArray array2=file2.read(5);
qDebug()<<"first 5 byte "<<array2;
qDebug()<<"current file ptr pos "<<file2.pos();
// file.seek(pos) 读取的是从pos+1个字节开始的(pos==1为第一个字节)
file2.close();
文件监视/过滤
private slots:
void showDirMessage(const QString &path); // 传递一个路径,引用方式,且不希望被修改
private:
Ui::Widget *ui;
QFileSystemWatcher monitor;
#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
#include <QDir>
#include <QStringList>
#include <QFileSystemWatcher> // 文件监视器
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QDir mydir(QDir::currentPath());
qDebug()<<mydir;
QDir mydir2("f:/qt-learning/exp10");
ui->listWidget->addItem(mydir2.absolutePath());
ui->listWidget->addItems(mydir2.entryList());
// 设置文件类型过滤器
mydir2.setNameFilters(QStringList("*.cpp"));
// 文件监视器 判断是否有改动:删除、改动、增加
mydir2.mkdir("monitorDir");
connect(&monitor,&QFileSystemWatcher::directoryChanged,this,&Widget::showDirMessage); // 监视文件夹变化
connect(&monitor,&QFileSystemWatcher::fileChanged,this,&Widget::showDirMessage); // 监视文件变化
monitor.addPath("f:/qt-learning/exp10/monitorDir"); // 监视文件夹
monitor.addPath("f:/qt-learning/exp10/monitorDir/test.txt"); // 监视文件
}
Widget::~Widget()
{
delete ui;
}
void Widget::showDirMessage(const QString &path)
{
if (path=="f:/qt-learning/exp10/monitorDir")
{
ui->listWidget->addItem("f:/qt-learning/exp10/monitorDir 目录发生改变");
}
else if (path=="f:/qt-learning/exp10/monitorDir/test.txt")
{
ui->listWidget->addItem("f:/qt-learning/exp10/monitorDir/test.txt 文件发生改变");
}
}
文件操作进阶
QTextStream
/*
QTextStream 类 提供了很多读写文件相关方法
*/
#include <QFile>
#include <QDebug>
#include <QString>
#include <QTextStream>
int main(int argc,char* argv[]){
// 创建QFile对象
QFile file("./demo2.txt");
// 对文件进行写操作
if (!file.open(QIODevice::WriteOnly|QIODevice::Text)){
qDebug()<<"文件打开失败";
}
QTextStream out(&file); // 将文件转换为文本流的方式进行存储
//QTextStream类重载了运算符<< >>
out<<(QString)"ex1\n"<<(QString)"ex2";
file.close();
// 读文本
if (!file.open(QIODevice::ReadOnly|QIODevice::Text)){
qDebug()<<"文件打开失败";
}
QTextStream in(&file);
while (!in.atEnd()){
QString str;
// 从文件中读取一个字符串
in>>str;
qDebug()<<str;
}
file.close();
return 0;
}
例子2
注意readline
\n
的问题没有解决???
#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QFile>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QTextStream>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QString fileName=QFileDialog::getOpenFileName(this,"打开文件","./");
ui->lineEdit->setText(fileName);
QFile file(fileName);
file.open(QIODevice::ReadOnly);
// 创建文本流
// 将一个文件关联一个流,将文件转换为流
// 操作这个流 等于 操作这个文件
QTextStream textStream(&file);
textStream.setEncoding(QStringConverter::Utf8); // 设置流的编码方式
QByteArray streamArray;
while (!textStream.atEnd())
{
streamArray+=textStream.readLine().toUtf8();
}
ui->textEdit->setText(streamArray);
file.close();
}
Widget::~Widget()
{
delete ui;
}
QDataStream
https://blog.csdn.net/qq_38832450/article/details/102587454
例子1
QFile file2("./test2.dat");
file2.open(QIODevice::WriteOnly);
// 将文件绑定到数据流上
QDataStream dataInStream(&file2);
dataInStream<<QString("hello world")<<QString("hello qt")<<(qint32)65;
file2.close();
file2.open(QIODevice::ReadOnly);
QDataStream dataOutStream(&file2);
QString str1,str2;
qint32 num;
dataOutStream>>str1>>str2>>num;
qDebug()<<str1<<str2<<num;
// dataOutStream>>str1>>num; // ERROR
// qDebug()<<str1<<num; // ERROR
file2.close();
- QDataStream 与QByteArray
https://blog.csdn.net/qq_40206060/article/details/111614662
借助QDataStream 实现数据与QByteArray的关联,输入与输出
伪代码
/* 数据流操作音视频 */
// 伪代码
QImage image("path");
QByteArray imageArray; // 相当于内存区域,内存块
// 通过流的方式,对内存块进行读写操作
QDataStream imageStream(&imageArray,QIODevice::ReadWrite); // 将数据流绑定到内存块
// 通过数据流的方式,将数据保存到内存块中
imageStream<<imag
- QDataStream 与QBuffer
https://blog.csdn.net/qq_44519484/article/details/108010891
进阶思考
QString
转QDataStream
后会增加一些头数据,比如文本的长度
QFile file("./7.信号和槽.wmv");
QFileInfo info(file.fileName());
qDebug()<<info.fileName()<<" "<<info.size(); // "7.信号和槽.wmv" 125554598
QByteArray arr26=info.fileName().toUtf8();
qDebug()<<arr26<<" "<<arr26.toHex()<<" "<<arr26.size(); // "7.\xE4\xBF\xA1\xE5\x8F\xB7\xE5\x92\x8C\xE6\xA7\xBD.wmv" "372ee4bfa1e58fb7e5928ce6a7bd2e776d76" 18
QByteArray arr27;
QDataStream out(&arr27,QIODevice::WriteOnly);
out<<info.fileName();
qDebug()<<arr27<<" "<<arr27.toHex()<<" "<<arr27.size(); // "\x00\x00\x00\x14\x00""7\x00.O\xE1S\xF7T\x8Ci\xFD\x00.\x00w\x00m\x00v" "000000140037002e4fe153f7548c69fd002e0077006d0076" 24
QDataStream in(&arr27,QIODevice::ReadOnly);
QString filename;
in>>filename;
qDebug()<<filename; // "7.信号和槽.wmv"
QByteArray arr28;
QDataStream out2(&arr28,QIODevice::WriteOnly);
out2<<info.fileName().toUtf8();
qDebug()<<info.fileName().toUtf8().size(); // 18
qDebug()<<arr28<<" "<<arr28.toHex()<<" "<<arr28.size(); // "\x00\x00\x00\x12""7.\xE4\xBF\xA1\xE5\x8F\xB7\xE5\x92\x8C\xE6\xA7\xBD.wmv" "00000012372ee4bfa1e58fb7e5928ce6a7bd2e776d76" 22
QDataStream in2(&arr28,QIODevice::ReadOnly);
QByteArray filename2;
in2>>filename2;
qDebug()<<filename2<<" "<<QString(filename2); // "7.\xE4\xBF\xA1\xE5\x8F\xB7\xE5\x92\x8C\xE6\xA7\xBD.wmv" "7.信号和槽.wmv"
QBuffer
- QBuffer与QByteArray
https://blog.csdn.net/qq_44519484/article/details/108010891
QBuffer 是操作QByteArray的接口类
QDataStream 是一个操作QBuffer的接口类