1. 程式人生 > >QT串列埠助手(五):檔案操作

QT串列埠助手(五):檔案操作

> 作者:zzssdd2 > > E-mail:[email protected] # 一、前言 開發環境:**Qt5.12.10 + MinGW** > 功能 - 檔案的傳送 - 資料的儲存 > 知識點 - `QFile`類的使用 - `QTimer`類的使用 - 文字的轉碼與編碼識別 - `QPushButton`、`QProgressBar`控制元件的使用 ![](https://img2020.cnblogs.com/blog/2193174/202102/2193174-20210207230758495-4911234.png) # 二、功能實現 本章功能主要包含兩個方面,一是通過串列埠傳送選定的文字檔案,二是將接收的資料儲存為本地文字檔案。最後還有對[《QT串列埠助手(三):資料接收》](https://www.cnblogs.com/zzssdd2/p/14319615.html)章節內容進行一個補充擴充套件。 ## 2.1、檔案開啟 當`選擇檔案`按鈕點選後,觸發點選訊號對應的槽函式,在槽函式中進行檔案的開啟與讀取: ```c++ /*選擇並開啟檔案*/ QString curPath = QDir::currentPath(); //系統當前目錄 QString dlgTitle = "開啟檔案"; //對話方塊標題 QString filter = "文字檔案(*.txt);;二進位制檔案(*.bin *.dat);;所有檔案(*.*)"; //檔案過濾器 QString filepath = QFileDialog::getOpenFileName(this,dlgTitle,curPath,filter); QFileInfo fileinfo(filepath); if (filepath.isEmpty()) { QMessageBox::warning(this,"警告","檔案為空"); return; } //檔案路徑顯示到傳送框 ui->Send_TextEdit->clear(); ui->Send_TextEdit->appendPlainText(filepath); QFile file(filepath); if (!file.exists()) { QMessageBox::warning(this,"警告","檔案不存在"); return; } if (!file.open(QIODevice::ReadOnly)) { QMessageBox::warning(this,"警告","檔案開啟失敗"); return; } ``` ## 2.2、編碼判斷 因為應用程式預設使用的編碼為*UTF-8*,如果開啟*GBK*格式編碼的檔案就會亂碼,所以需要判斷檔案的編碼,如果不是UTF-8則需要對檔案進行編碼轉換。 ```c++ /* 設定應用程式的編碼解碼器 */ QTextCodec *codec = QTextCodec::codecForName("UTF-8"); QTextCodec::setCodecForLocale(codec); ``` > - [static] QTextCodec *QTextCodec::codecForName(const char \*name) > > Searches all installed QTextCodec objects and returns the one which best matches *name*; the match is case-insensitive. Returns 0 if no codec matching the name *name* could be found. > > - [static] void QTextCodec::setCodecForLocale(QTextCodec **c*) > > Set the codec to *c*; this will be returned by codecForLocale(). If *c* is a null pointer, the codec is reset to the default. > > This might be needed for some applications that want to use their own mechanism for setting the locale. > > Warning: This function is not reentrant. ```c++ /* 判斷編碼 */ QTextCodec::ConverterState state; QTextCodec *codec = QTextCodec::codecForName("UTF-8"); FileText = codec->toUnicode(data.constData(),data.size(),&state); //若有無效字元則是GBK編碼 if (state.invalidChars > 0) { //轉碼後返回 FileText = QTextCodec::codecForName("GBK")->toUnicode(data); } else { FileText = data; } ``` 對檔案進行上述的處理後,如果是GBK編碼則也能夠正確的讀取了。 > - QString QTextCodec::toUnicode(const char \**input*, int *size*, QTextCodec::ConverterState **state* = nullptr) const > > Converts the first *size* characters from the *input* from the encoding of this codec to Unicode, and returns the result in a QString. > > The *state* of the convertor used is updated. > > - QString QTextCodec::toUnicode(const QByteArray &*a*) const > > Converts *a* from the encoding of this codec to Unicode, and returns the result in a QString. ![](https://img2020.cnblogs.com/blog/2193174/202102/2193174-20210207230717670-1399417024.png) ## 2.3、檔案讀取 檔案開啟後,需要對檔案型別進行判斷,然後進行檔案資料的讀取: ```c++ /*判斷檔案型別*/ int type = 0; QMimeDatabase db; QMimeType mime = db.mimeTypeForFile(filepath); if (mime.name().startsWith("text/")) { type = 1; //文字檔案 } else if (mime.name().startsWith("application/")) { type = 2; //二進位制檔案 } ``` > QMimeType QMimeDatabase::mimeTypeForFile(const QString&*fileName*, QMimeDatabase::MatchMode *mode* = MatchDefault) const > > Returns a MIME type for the file named *fileName* using *mode*. > > This is an overloaded function. > > > > QMimeType 類描述檔案或資料的型別,由 MIME 型別字串表示,獲取到檔案型別後接下來就知道應該使用什麼方法讀取檔案內容了。常見檔案型別如下: > > | 描述(startsWith) | 型別 | 示例 | > | ---------------- | --------------------- | -------------------------------------------------------- | > | text | 普通文字 | text/plain, text/html, text/css, text/javascript | > | image | 影象檔案(包含動態gif) | image/gif, image/png, image/jpeg, image/bmp, image/webp | > | audio | 音訊檔案 | audio/wav, audio/mpeg, audio/midi, audio/webm, audio/ogg | > | video | 視訊檔案 | video/mp4, video/x-flv, video/webm, video/ogg | > | application | 二進位制資料 | application/xml, application/pdf | ```c++ /*讀取檔案*/ switch(type) { case 1: { //QIODevice讀取普通文字 QByteArray data = file.readAll(); file.close(); if (data.isEmpty()) { QMessageBox::information(this, "提示", "檔案內容空"); return; } /* 判斷編碼 */ } break; case 2: { int filelen = fileinfo.size();