QT--文件操作和文件读写
文件操作和文件读写
- QFile 类用于对文件进行操作,它继承自 QIODevice,可以进行读写操作。主要用于打开、关闭、读取、写入和管理文件。
1. 首先要指定文件路径
- QFile fn(“文件路径”);
- 也可以通过文件对话框来选择文件getOpenFileName
函数原型
QString QFileDialog::getOpenFileName(
QWidget *parent = nullptr,
const QString &caption = tr("Open File"),
const QString &dir = QString(),
const QString &filter = QString(),
QString *selectedFilter = nullptr,
QFileDialog::Option options = QFileDialog::Options()
);
代码举例
QString fn = QFileDialog::getOpenFileName(this,"openFile","/home/QFile","*.txt;;*.h *.c");
2. 指定文件打开权限,即打开之后能够操作什么
-
假设已经给fn指定好路径了,那么则有fn.open(权限)
-
文件打开权限
函数 | 值 | 描述 |
---|---|---|
QIODevice::NotOpen | 0x0000 | 未打开模式。文件没有被打开。 |
QIODevice::ReadOnly | 0x0001 | 只读模式。文件被打开以进行读取操作。 |
QIODevice::WriteOnly | 0x0002 | 只写模式。文件被打开以进行写入操作。 |
QIODevice::ReadWrite | 0x0003 | 读写模式。文件被打开以进行读取和写入操作。 |
QIODevice::Append | 0x0004 | 追加模式。文件被打开以在末尾追加数据,不会覆盖原有内容。 |
QIODevice::Truncate | 0x0008 | 截断模式。如果文件存在,将清空文件内容。 |
QIODevice::Text | 0x0010 | 文本模式。以文本模式打开文件,行结束符会自动转换为系统特定的格式(例如\n 在Unix/Linux系统中,\r\n 在Windows系统中)。 |
QIODevice::Unbuffered | 0x0040 | 无缓冲模式。禁用缓冲区,直接操作设备。 |
QIODevice::NewOnly | 0x0100 | 仅在文件不存在时创建文件。如果文件已存在,操作将失败。 |
QIODevice::Existing | 0x0200 | 仅在文件已存在时打开文件。如果文件不存在,操作将失败。 |
QIODevice::UnrestrictedRead | 0x0400 | 允许未受限制的读取访问。可以用于某些情况下需要特别权限的读取操作。 |
3.对打开方式返回值判断
- 对open方式打开的文件都有一个布尔类型的返回值,成功为true,失败为false,可以借此判断是否以指定方式打开成功。
- 代码举例
bool ret = fn.open(QIODevice::ReadOnly);
if(ret == false){
ui->textEdit->setText("以只读方式打开失败");
return;
}
4. 文件的读和写
- 小知识
- char buf[2024] = {0}; 这段代码的作用是创建一个长度为 2024的字符数组,并将数组中的每个字符元素初始化为 0,也就是空字符 ‘\0’。在C/C++中,字符串是以空字符 ‘\0’ 结束的字符序列。这样的初始化确保了数组在使用前不会包含任何未定义的值,非常适合用来存储字符串或者二进制数据。
1.文件的读
- 指定一个char类型的数组用来存储读的数据。可以指定较大的数组来一次性读取完所有的数据。也可以创建文本流的方式从文件中读取数据(灵活)。
- 一次性
char buf[20400] ={0};
r = fn.read(buf,sizeof(buf));
if(r<0){
ui->textEdit->setText("读取失败");
return;
}
ui->textEdit->setText(buf);
- 一行一行读
//需要包含QTextStream头文件
QTextStream fntext(&fn);fn是QFile类型,指定了文件的读取路径
ui->textEdit->clear();
while(!fntext.atEnd()){//fntext.atEnd():检查文件是否已经读取到末尾。
QString line =fntext.readLine();
ui->textEdit->append(line);
}
2. 文件的写
- 有重新写入和追加写入两种方式,一般用的比较多的是追加写入
- 追加写入
- 打开文件的方式是Append。文件写指针会自动定位到文件末尾,从而确保新写入的数据不会覆盖文件中已有的数据。
- 获取写入的文本QString txtStr = ui->textEdit->toPlainText();
- 将QString类型文本转换为std::string类型,也就是c++类型,因此可以使用C++标准库的字符串操作std::string str = txtStr.toStdString();
- 因为write的参数是指针,长度。所以用c_str();获取c风格字符串指针,是常量指针喔。*const char pchar = str.c_str();
- 为了保证QString 在转换为本地8位编码后正确地写入文件,处理可能存在的多字节字符。简单的说是因为文字的编码格式不一样,有utf-8,Gbk这种编码。采用toLocal8bit().length()能够获得一致的长度,从而避免字符截断或编码错误txtStr.toLocal8Bit().length()
- write写入,fn.write(pchar,txtStr.toLocal8Bit().length());,它也有返回值。返回小于0的数表示写入失败。
void Widget::btnAppendClickedSlotFun()
{
int r;
QFile fn(ui->lineEdit->text());
bool ret = fn.open(QIODevice::Append);
if(ret == false){
ui->textEdit->setText("追加写入失败");
return;
}
QString txtStr = ui->textEdit->toPlainText();
std::string str = txtStr.toStdString();
const char *pchar = str.c_str();
r = fn.write(pchar,txtStr.toLocal8Bit().length());
if(r<0){
ui->textEdit->setText("写入失败");
return;
}
fn.close();
}
- 重新写入
- 它和追加写入的方式只有打开文件的方式的不一样,也就导致文件写指针的位置不一样。
- fn.open(QIODevice::WriteOnly|QIODevice::Truncate);//writeonly保证了文件以写的方式打开,truncate保证了文件当中有内容也被清空。
void Widget::btnWriteClickedSlotFun()
{
int r;
QFile fn(ui->lineEdit->text());
bool ret = fn.open(QIODevice::WriteOnly|QIODevice::Truncate);
if(ret==false){
ui->textEdit->setText("打开写入失败");
return;
}
QString txtStr = ui->textEdit->toPlainText();
std::string stdstr = txtStr.toStdString();
const char *pchar = stdstr.c_str();
r = fn.write(pchar,txtStr.toLocal8Bit().length());
if(r<0){
ui->textEdit->setText("写入失败");
return;
}
fn.close();
}
- 注意点
- 当我们将文件给读取出来,并在文件内容上修改,一般采用重新写入。追加写入可以加日志之类的。
4. 文件的创建、关闭和删除
- 文件的创建,给fn一个不存在的文件路径名即可
void Widget::btnCreateClickedSlotFun()
{
QFile fn(ui->lineEdit->text());
fn.open(QIODevice::WriteOnly);//避免空文件打开时警告
fn.close();
}
- 文件的关闭使用close函数即可。**fn.close();**读写完毕之后都要关闭
- 文件的删除使用remove函数即可。fn.remove();
5.整体代码
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void btnOpenClickedSlotFun();
void btnReadClickedSlotFun();
void btnWriteClickedSlotFun();
void btnAppendClickedSlotFun();
void btnDeleteClickedSlotFun();
void btnCreateClickedSlotFun();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
//widget.h
#include "widget.h"
#include "ui_widget.h"
#include<QTextStream>
#include<QFileDialog>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->lineEdit->setText("打开文件存放的路径");
ui->btnOpen->setText("打开文件");
connect(ui->btnOpen,SIGNAL(clicked()),this,SLOT(btnOpenClickedSlotFun()));
ui->btnRead->setText("读取文件");
connect(ui->btnRead,SIGNAL(clicked()),this,SLOT(btnReadClickedSlotFun()));
ui->btnWrite->setText("写入文件");
connect(ui->btnWrite,SIGNAL(clicked()),this,SLOT(btnWriteClickedSlotFun()));
ui->btnAppend->setText("追加写入文件");
connect(ui->btnAppend,SIGNAL(clicked()),this,SLOT(btnAppendClickedSlotFun()));
ui->btnDelete->setText("删除文件");
connect(ui->btnDelete,SIGNAL(clicked()),this,SLOT(btnDeleteClickedSlotFun()));
ui->btnCreate->setText("创建文件");
connect(ui->btnCreate,SIGNAL(clicked()),this,SLOT(btnCreateClickedSlotFun()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::btnOpenClickedSlotFun()
{
QString fn = QFileDialog::getOpenFileName(this,"openFile",
"/mnt/hgfs/linux_learn/QT_teacher_information/");
if(fn.isEmpty()){
ui->lineEdit->setText("选中目录失败,请重新选中");
return ;
}
ui->lineEdit->setText(fn);
}
void Widget::btnReadClickedSlotFun()
{
int r;
QFile fn(ui->lineEdit->text());
bool ret = fn.open(QIODevice::ReadOnly);
if(ret == false){
ui->textEdit->setText("打开失败");
return;
}
/* char buf[20400] ={0};
r = fn.read(buf,sizeof(buf));
if(r<0){
ui->textEdit->setText("读取失败");
return;
}
ui->textEdit->setText(buf);*/
QTextStream fntext(&fn);
ui->textEdit->clear();
while(!fntext.atEnd()){
QString line =fntext.readLine();
ui->textEdit->append(line);
}
fn.close();
}
void Widget::btnWriteClickedSlotFun()
{
int r;
QFile fn(ui->lineEdit->text());
bool ret = fn.open(QIODevice::WriteOnly|QIODevice::Truncate);
if(ret==false){
ui->textEdit->setText("打开写入失败");
return;
}
QString txtStr = ui->textEdit->toPlainText();
std::string stdstr = txtStr.toStdString();
const char *pchar = stdstr.c_str();
r = fn.write(pchar,txtStr.toLocal8Bit().length());
if(r<0){
ui->textEdit->setText("写入失败");
return;
}
fn.close();
}
void Widget::btnAppendClickedSlotFun()
{
int r;
QFile fn(ui->lineEdit->text());
bool ret = fn.open(QIODevice::Append);
if(ret == false){
ui->textEdit->setText("追加写入失败");
return;
}
QString txtStr = ui->textEdit->toPlainText();
std::string str = txtStr.toStdString();
const char *pchar = str.c_str();
r = fn.write(pchar,txtStr.toLocal8Bit().length());
if(r<0){
ui->textEdit->setText("写入失败");
return;
}
fn.close();
}
void Widget::btnDeleteClickedSlotFun()
{
QFile fn(ui->lineEdit->text());
bool r = fn.remove();
if(r==false){
ui->textEdit->setText("删除失败");
return;
}else{
ui->textEdit->setText("删除成功");
}
}
void Widget::btnCreateClickedSlotFun()
{
QFile fn(ui->lineEdit->text());
fn.open(QIODevice::WriteOnly);//避免空文件打开时警告
fn.close();
}
- 布局
原文地址:https://blog.csdn.net/m0_51830537/article/details/140580063
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!