20200601
【打开文件】
两个类:(1)文件对话框(2)对文件操作的类QFile;
【文件对话框】#include <QFileDialog>
优先通过静态形式使用
QString getExistingDirectory 判断目录是否存在
QUrl getExistingDirectoryUrl 判断地址是否存在 Url是上网用的
QString getOpenFileName 打开文件名,返回的QString类型是文件的绝对路径
QStringList getOpenFileNames 有无s,有无List:表示一个多选,一个单选
【保存文件】
QString getSaveFileName 保存时不能同时保存多个,只能单个单个保存
若要保存多个:遍历一下就好了
fopen系列当然可以对文件进行操作
不过这里,我们用QFile类对文件进行操作:可以用静态函数,也可以用非静态函数,这两种类似
(1)静态函数
(2)非静态函数
如果不知道怎么用,就去看 Detailed Description 。
这里有两种形式可以使用:普通形式和文本流形式都带有缓冲区
不同之处在于:
普通 file 类形式:必须对文件全部操作完以后,才能进行下一次操作。
QTextStream流形式:可以操作一部分,等数据库来了,再操作一部分。可以分批来做。类似于河流,取一瓢无影响。
直接调用 f 操作的小弊端:适合小文件。对于大文件,建议使用QTextStream文件流的方式进行操作。
思考:对视频进行文本流操作,可行吗?
NONONO不行,视频是二进制形式存储的,而文本流是文本形式存储的,如果强行操作的话,数据会乱码的。
————————————————————分割线——————————————
界面布局:PushButton*2(打开/保存),TextEdit*1(显示)
dir路径 "../20200601/"
弹出对话框,选择要打开哪个文件(filter 筛选文件)
结果展示:
、
接下来实现:打开文件
不知道怎么用的就F1查看帮助文档
Truncate 截取 Unbuffered 二进制
实现效果如下:选择文件,打开,显示出来
当你一开始不知道怎么使用的时候,可以采用如下第二种方式:
qint64 QIODevice::read(char *data, qint64 maxSize)
memset(buf,0,MSG_LEN); //添加头文件 #include <string.h> //清空后开始读
更常用的一种方式是:readLine();
注意:像这种参数为0的情况( = 0)意味着可以不给,它有默认参数。
读取所有的 readAll
上面,我们是用Qt本身的(1)QFile进行直接读取
接下来用文本流进行读取: //(2)QTextStream文本流形式读取:支持大文本文件的读取(大文件 & 文本文件)
保存文件:
QFileDialog::getSaveFileName( );
//弹出对话框,显示文件要保存的位置————filter参数:筛选要存为的文本文件格式
(1) //QFile直接写数据
//QFile直接写数据
myFile->write(ui->textEdit->toPlainText().toLocal8Bit());// toPlainText 获取整个页面的,转换成ByteArray的。 QByteArray QString::toLocal8Bit() const
myFile->close();
(2) //文本流写数据
#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QFile>
#include <QMessageBox>
#include <string.h>
#include <QTextStream>
#define MSG_LEN 10241
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
Init();//调用
}
Widget::~Widget()
{
delete ui;
}
void Widget::Init(){
myFile = new QFile(this);//为myFile分配空间
}
void Widget::on_btn_OpenFile_clicked()
{
//弹出对话框,选择要打开哪个文件(默认定位到代码目录下)
QString filename = QFileDialog::getOpenFileName(this,"Get File","../20200601/",
"SOURCES(*.cpp);;HEADERS(*.h);;FORMS(*.ui)");//谁放最前面,谁就是默认的
if(filename.isEmpty()){
QMessageBox::warning(this,"Warning","文件未选中"); //没有选择文件
return;
}
//打开文件open
myFile->setFileName(filename);
bool ret = myFile->open(QIODevice::ReadOnly | QIODevice::Text);//【只读】先看参数,再看返回值
if(!ret){
QMessageBox::warning(this,"warning","打开失败!");
return;
}
// char buf[MSG_LEN+1]={0};
//(1)QFile直接读取
/*
//判断是否在末尾:不在末尾
while(!myFile->atEnd()){
// QByteArray ba = myFile->read(MSG_LEN);
// QString str = QString(ba); //把QByteArray转换为QString类型
// ui->textEdit->append(str); //追加,不是替换
// memset(buf,0,MSG_LEN);//添加头文件#include <string.h> //清空后开始读
// myFile->read(buf,MSG_LEN);//char*转换为QString类型
// QString str = QString(buf);
// ui->textEdit->append(str);
// QByteArray ba = myFile->readLine();
// QString str = QString(ba);
// ui->textEdit->append(str);
//读取所有的
QByteArray ba = myFile->readAll();
QString str = QString(ba);
ui->textEdit->append(str);
}
*/
//(2)QTextStream文本流形式读取:支持大文本文件的读取
QTextStream text(myFile); //关联,myFile是指针
while (!text.atEnd()) {
QString str = text.readAll();
ui->textEdit->append(str);
}
myFile->close();
}
void Widget::on_btn_SaveFile_clicked()
{
//弹出对话框,显示文件要保存的位置————filter参数:筛选要存为的文本文件格式
QString filename = QFileDialog::getSaveFileName(this,"保存文件","/E:/QtCode/20200601","Text(*.cpp *.h)"); //返回值是QString
if(filename.isEmpty())
{
QMessageBox::warning(this,"warning","File Can't Select");//对话框页面没有保存,点击关闭窗口或取消时的显示内容
return;
}
//不为空的时候
myFile->setFileName(filename);
bool ret = myFile->open(QIODevice::WriteOnly | QIODevice::Text); //【只写】让其具有创建文件的功能
if(!ret){
QMessageBox::warning(this,"warning","Open Failed");
return;
}
//(1) QFile直接写数据
// myFile->write(ui->textEdit->toPlainText().toLocal8Bit());// toPlainText 获取整个页面的,转换成ByteArray的。 QByteArray QString::toLocal8Bit() const
// myFile->close();
//先接收页面的值,然后再转————文件多的时候,要用遍历的形式去写
// QString str = ui->textEdit->toPlainText();
// myFile->write(str.toLocal8Bit());
// myFile->close();
//(2) 文本流形式写数据
QTextStream stream(myFile); //先声明,并关联
QString str = ui->textEdit->toPlainText();
stream << str;
stream.flush();//关闭之前,强制刷新
myFile->close();//关闭
}
这存在一个弊端:保存文件名和原有文件名相同时候,就给替换了
原先我以为如下————后来代码中把 if(!filename.isEmpty()) 改为了 if(filename.isEmpty())
//如果所存文件的文件名和已有文件的文件名重复,则不能被保存。
——————————————————————分割线——————————————————————
【错误消息框】 #include <QErrorMessage>
一定要学会:F1帮助文档,自己学会用。
在帮助文档中,选中一个变量,可以【Ctrl + F】查找它所有被用到的地方。
创建对象
第1步:头文件中引入
第2步:定义一个指针形式的对象名
第3步:分配空间
在帮助文档中定位
不断根据结果来修正(根据F1帮助文档中的example来定位使用)
完成!!!