QT--文件操作和文件读写

avatar
作者
筋斗云
阅读量:0

文件操作和文件读写

  • QFile 类用于对文件进行操作,它继承自 QIODevice,可以进行读写操作。主要用于打开、关闭、读取、写入和管理文件。
1. 首先要指定文件路径
  1. QFile fn(“文件路径”);
  2. 也可以通过文件对话框来选择文件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. 指定文件打开权限,即打开之后能够操作什么
  1. 假设已经给fn指定好路径了,那么则有fn.open(权限)

  2. 文件打开权限

函数描述
QIODevice::NotOpen0x0000未打开模式。文件没有被打开。
QIODevice::ReadOnly0x0001只读模式。文件被打开以进行读取操作。
QIODevice::WriteOnly0x0002只写模式。文件被打开以进行写入操作。
QIODevice::ReadWrite0x0003读写模式。文件被打开以进行读取和写入操作。
QIODevice::Append0x0004追加模式。文件被打开以在末尾追加数据,不会覆盖原有内容。
QIODevice::Truncate0x0008截断模式。如果文件存在,将清空文件内容。
QIODevice::Text0x0010文本模式。以文本模式打开文件,行结束符会自动转换为系统特定的格式(例如\n 在Unix/Linux系统中,\r\n 在Windows系统中)。
QIODevice::Unbuffered0x0040无缓冲模式。禁用缓冲区,直接操作设备。
QIODevice::NewOnly0x0100仅在文件不存在时创建文件。如果文件已存在,操作将失败。
QIODevice::Existing0x0200仅在文件已存在时打开文件。如果文件不存在,操作将失败。
QIODevice::UnrestrictedRead0x0400允许未受限制的读取访问。可以用于某些情况下需要特别权限的读取操作。
3.对打开方式返回值判断
  1. 对open方式打开的文件都有一个布尔类型的返回值,成功为true,失败为false,可以借此判断是否以指定方式打开成功。
  2. 代码举例
bool ret = fn.open(QIODevice::ReadOnly);     if(ret == false){         ui->textEdit->setText("以只读方式打开失败");         return;     } 
4. 文件的读和写
  1. 小知识
  • 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. 文件的写
  1. 有重新写入和追加写入两种方式,一般用的比较多的是追加写入
  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(); } 
  1. 重新写入
    • 它和追加写入的方式只有打开文件的方式的不一样,也就导致文件写指针的位置不一样。
    • 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(); } 
  1. 注意点
    • 当我们将文件给读取出来,并在文件内容上修改,一般采用重新写入。追加写入可以加日志之类的。
4. 文件的创建、关闭和删除
  1. 文件的创建,给fn一个不存在的文件路径名即可
void Widget::btnCreateClickedSlotFun() {     QFile fn(ui->lineEdit->text());     fn.open(QIODevice::WriteOnly);//避免空文件打开时警告     fn.close(); } 
  1. 文件的关闭使用close函数即可。**fn.close();**读写完毕之后都要关闭
  2. 文件的删除使用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(); }   
  • 布局
    在这里插入图片描述

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!