「Qt」文件讀寫操作

0、引言

? ? ? ? 我們知道 C 和 C++ 都提供了文件讀寫的類庫,不過 Qt 也有一套自己的文件讀寫操作;本文主要介紹 Qt 中進行文件讀寫操作的類 —— QFile

1、QFileDialog 文件對話框

? ? ? ? 一般的桌面應用程序,當我們想要打開一個文件時,通常會彈出一個文件對話框。在 Qt 中,文件對話框使用 QFileDialog 類實現。

????????QFileDialog 類允許用戶遍歷文件系統,以便選擇一個或多個文件或目錄。

? ? ? ? 最簡單的創建 QFileDialog 的方法是使用靜態函數:

fileName = QFileDialog::getOpenFileName(this,tr("Open Image"), "/home", tr("Image Files (*.png *.jpg *.bmp)"));

? ? ? ? tr() 是 Qt 中的一個函數,用于將字符串標記為可翻譯的字符串。這個函數的作用是在運行時,根據配置在 Qt Linguist 工具中的翻譯,將輸入字符串翻譯成適當的語言。

????????這意味著,如果您的應用程序支持多種語言,并且在 Qt Linguist 工具中配置了相應的翻譯,那么這些字符串將在運行時被翻譯成用戶選擇的語言。

? ? ? ? 在上面的例子中,我們使用靜態方法創建了一個模態 QFileDialog(什么是 模態對話框?)。該對話框初始顯示 "/home" 目錄中的內容,并顯示與字符串 "Image files (*.png *.jpg *.bmp)" 中給出的模式匹配的文件。文件對話框的父窗口設置為 this,窗口標題設置為 "Open Image"

? ? ? ? 如果你想要使用多個過濾器,請用 兩個分號 分隔每一個過濾器。例如:

"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"

? ? ? ? 如果您想要不使用任何文件過濾器,請直接傳遞空字符串。或者傳遞

"All Files (*)"

? ? ? ? (了解更多...)

????????在上面的例子中我們可以嘗試使用 QFileDialog 選擇一個文件并將 fileName 打印到單行文本框,最終實現效果類似于下圖:

文件對話框

2、QFile

? ? ? ? QFileDialog 只是幫助我們完成了獲取文件的絕對路徑(什么是 絕對路徑(以 Windows 系統為例)?)的工作;接下來才是要進行文件讀寫的操作。在 Qt 中,文件讀寫通常與 QFile 類相關。

? ? ? ? 💬 有關 QFile 的用法,還請讀者參考 QFile 的官方文檔,這里筆者不再贅述。下面主要介紹 QFileDialog 類配合 QFile 類的使用案例:

2.1、QFile 讀操作

? ? ? ? 以下代碼展示了 QFileDialog 類配合 QFile 類打開并讀取一張圖片文件(我們在與 QPushButton::clicked 信號關聯的槽函數中讀取圖片文件):

//點擊“打開”按鈕,彈出文件選擇對話框
connect(ui->pushButton, &QPushButton::clicked, this, [=](){QString fileName = QFileDialog::getOpenFileName(this,tr("Open Image"), "/home" , tr("Image Files (*.png *.jpg *.bmp *.svg)"));//將路徑放到 LineEdit 中ui->lineEdit->setText(fileName);//使用文件的絕對路徑實例化 QFileQFile file(fileName);//只讀模式打開文件file.open(QIODevice::ReadOnly);//全部讀取QByteArray bytes = file.readAll();//生成 QImage 實例QImage image = QImage::fromData(bytes);//生成 QPixmap 實例并顯示在 QLabel 控件上ui->label->setPixmap(QPixmap::fromImage(image));//關閉文件file.close();
});

????????使用 QFileDialog 配合 QFile,我們可以做到在運行時選擇并讀取圖片文件:

讀取圖片文件并顯示


????????此外,我們還可以嘗試使用 QFileDialog 配合 QFile 打開文本文件,只需略微修改上面示例代碼中的槽函數即可:

  • ?在 Linux(Ubuntu) 下,你可以使用如下命令創建文本文件:
    touch filename.txt
  • 創建完成后,在其中編輯一些字符,保存后就可以使用如下命令查看該文本文件的字符編碼格式:
    file filename.txt# 如果文本文件中只有英文字符,則編碼格式為 ASCII;
    # 如果帶有中文字符,則編碼格式為 UTF-8 Unicode。
  • 使用如下命令轉換文本文件的字符編碼格式(參考鏈接):
    sudo iconv -f 'utf-8' -t 'gbk' filename.txt > GbkText.txt
//點擊“打開”按鈕,彈出文件選擇對話框
connect(ui->pushButton, &QPushButton::clicked, this, [=](){QString fileName = QFileDialog::getOpenFileName(this,tr("Open Text File"), "/home" , tr("Text Files (*.txt)"));//將路徑放到 LineEdit 中ui->lineEdit->setText(fileName);//使用文件的絕對路徑實例化 QFileQFile file(fileName);//只讀模式打開文件file.open(QIODevice::ReadOnly);//全部讀取QByteArray bytes = file.readAll();//在 QLabel 文件上顯示文本ui->label->setText(bytes);//關閉文件file.close();
});

????????需要注意的是,QLabel::SetText()?方法接受一個 QString 類型的參數,而在上面的示例代碼中我們傳遞了一個字節數組作為參數。

? ? ? ? 巧合的是,QString 類提供了一個接受 QByteArray 類型的構造函數,這意味著這里會發生一次隱式轉換將 QByteArray 類型轉換為 QString 類型。不過,這個構造函數的轉換將會使用 UTF-8 格式解碼字符串。

? ? ? ? 這樣的隱式轉換可能會導致一些問題,特別是當你的文本文件不是 UTF-8 格式編碼時:

文本文件編碼問題
兩個文本文件內容一致,但 'GBK' 字符編碼格式文件會顯示亂碼

? ? ? ? 為了避免這樣的問題,我們可以嘗試使用一些 Qt 中專門用于編碼和解碼文本的類,比如 QTextCodec(在 Qt 5.15 過后已經部分棄用)和 QStringConverter 類;或者使用流來讀取文件(使用流的時候,默認情況下,QTextStream 假設文件以 UTF-8 編碼;但這可以使用QTextStream::setEncoding() 來改變)。

2.2、QFile 寫操作

????????除了讀操作,我們還可以使用 QFileDialog 類配合 QFile 類打開并向文件中寫入數據。下面是一個打開文本文件并向其中追加新的文本的示例,同樣略微修改上面示例代碼中的槽函數即可:

//點擊“打開”按鈕,彈出文件選擇對話框
connect(ui->pushButton, &QPushButton::clicked, this, [=](){QString fileName = QFileDialog::getOpenFileName(this,tr("Open Text File"), "/home" , tr("Text Files (*.txt)"));//將路徑放到 LineEdit 中ui->lineEdit->setText(fileName);//使用文件的絕對路徑實例化 QFileQFile file(fileName);//以追加的模式打開文件file.open(QIODevice::Append);//寫數據file.write("這是我寫入的文本!\n");//關閉文件file.close();//重新以只讀方式打開文件file.open(QIODevice::ReadOnly);QByteArray data;//當沒有到達文件末尾時while(!file.atEnd()){//按行讀取data += file.readLine();}ui->label->setText(data);//關閉文件file.close();
});

下面是運行效果:

QFile 寫操作

3、QFileInfo 文件信息

? ? ? ? QFileInfo?提供了文件在文件系統中的名稱和位置(路徑)、訪問權限以及是目錄還是符號鏈接等信息,還有文件的大小、最后修改/讀取時間等信息。此外,QFileInfo 也可以用來獲取關于 Qt 資源的信息。

????????QFileInfo 可以指向具有相對或絕對文件路徑的文件。絕對文件路徑以目錄分隔符 "/" 開頭(或在 Windows 上以驅動器規格開頭)。相對文件名以目錄名或文件名開頭,并指定相對于當前工作目錄的路徑。絕對路徑的一個例子是字符串 "/tmp/quartz"。相對路徑可能看起來像 "src/fatlib"。可以使用函數 isRelative() 檢查 QFileInfo 使用的是相對文件路徑還是絕對文件路徑。您可以調用 makeAbsolute() 函數將 QFileInfo 的相對路徑轉換為絕對路徑。

?? 注意:以冒號(:)開頭的路徑總是被認為是絕對路徑,因為它們表示一個 QResource

? ? ? ? QFileInfo 處理的文件是在構造函數中設置的(或者后續使用 setFile() 設置)。使用 exists() 查看文件是否存在并使用 size() 獲取其大小。

? ? ? ? 文件的類型通過 isFile()isDir()isSymLink() 獲得。symLinkTarget() 函數提供了符號鏈接指向的文件的名稱。

????????在 Unix(包括 macOS 和 iOS)上,該類中的屬性獲取器函數返回目標文件的時間和大小等屬性,而不是符號鏈接的時間和大小等屬性,這是因為 Unix 透明地處理符號鏈接。使用 QFile 打開符號鏈接可以有效地打開鏈接的目標。例如:

#ifdef Q_OS_UNIXQFileInfo info1("/home/bob/bin/untabify");
info1.isSymLink();          // returns true
info1.absoluteFilePath();   // returns "/home/bob/bin/untabify"
info1.size();               // returns 56201
info1.symLinkTarget();      // returns "/opt/pretty++/bin/untabify"QFileInfo info2(info1.symLinkTarget());
info2.isSymLink();          // returns false
info2.absoluteFilePath();   // returns "/opt/pretty++/bin/untabify"
info2.size();               // returns 56201#endif

????????在 Windows 上,快捷方式(.lnk 文件)目前被視為符號鏈接。與 Unix 系統一樣,屬性獲取器返回目標文件的大小,而不是 .lnk 文件本身。此行為已被棄用,可能會在 Qt 的未來版本中刪除,之后 .lnk 文件將被視為常規文件。

#ifdef Q_OS_WINQFileInfo info1("C:\\Users\\Bob\\untabify.lnk");
info1.isSymLink();          // returns true
info1.absoluteFilePath();   // returns "C:/Users/Bob/untabify.lnk"
info1.size();               // returns 63942
info1.symLinkTarget();      // returns "C:/Pretty++/untabify"QFileInfo info2(info1.symLinkTarget());
info2.isSymLink();          // returns false
info2.absoluteFilePath();   // returns "C:/Pretty++/untabify"
info2.size();               // returns 63942#endif

? ? ? ? 文件名稱的元素可以使用 path()fileName() 提取。fileName() 的部分可以用 baseName()suffix()?或 completeSuffix() 提取。QFileInfo 對象到由 Qt 類創建的目錄將不會有尾隨文件分隔符。如果您希望在自己的文件信息對象中使用尾隨分隔符,只需在構造函數或 setFile() 給出的文件名后附加一個。

? ? ? ? 文件的日期由 birthTime()lastModified()lastRead()fileTime() 返回。通過 isReadable()isWritable()isExecutable() 獲取文件的訪問權限信息。文件的所有權可以從 owner()ownerId()group()groupId() 中獲得。您可以使用 permission() 函數在單個語句中檢查文件的權限和所有權。

?? 注意:在 NTFS 文件系統上,出于性能原因,默認情況下禁用所有權和權限檢查。要啟用它,包括以下行:

extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;

然后通過對 qt_ntfs_permission_lookup 加 1 和減 1 來打開和關閉權限檢查。

qt_ntfs_permission_lookup++;     //啟用檢查
qt_ntfs_permission_lookup--;     //再次關閉檢查

?? 注意:由于這是一個非原子全局變量,所以只有在除主線程以外的任何線程啟動之前或除主線程以外的每個線程結束之后,才可以對 qt_ntfs_permission_lookup 進行遞增或遞減操作。


? ? ? ? 下面是一個 QFileDialog 類配合 QFileInfo 類獲取文件信息的代碼示例,同樣略微修改 2.1 小節示例代碼中的槽函數即可:

//點擊“打開”按鈕,彈出文件選擇對話框
connect(ui->pushButton, &QPushButton::clicked, this, [=](){QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"), "/home", tr("All Files (*)"));//將路徑放到 LineEdit 中ui->lineEdit->setText(fileName);QFileInfo info(fileName);QString str = "path() = " + info.path() + "\n"+ "filePath() = " + info.filePath() + "\n"+ "fileName() = " + info.fileName() + "\n"+ "baseName() = " + info.baseName() + "\n"+ "suffix() = " + info.suffix() + "\n"+ "completeSuffix() = " + info.completeSuffix() + "\n"+ "birthTime() = " + info.birthTime().toString();    //toString()方法可指定日期輸出格式ui->label->setText(str);
});

💬 在打印文件的日期信息時,可以指定輸出的格式,比如:

info.birthTime().toString("yyyy/MM/dd hh:mm:ss"); // 2023/08/16 21:12:34

(參考 QDateTimetoString() 方法了解更多)

運行效果:

QFileInfo 獲取文件信息

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40508.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40508.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40508.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php+echarts實現數據可視化實例

效果&#xff1a; 代碼&#xff1a; php <?php include(includes/session.inc); include(includes/SQL_CommonFunctions.inc); ?> <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv&quo…

OpenLayers入門,OpenLayers加載google街景地圖

專欄目錄: OpenLayers入門教程匯總目錄 前言 本章講解OpenLayers加載google街景地圖,無需科學上網,也可以正常訪問瓦片。 二、依賴和使用 "ol": "^6.15.1"使用npm安裝依賴npm install ol@6.15.1使用Yarn安裝依賴yarn add olvue中如何使用: vue項…

FastApi-1-結合sql 增/查demo

目錄 FastAPI學習記錄項目結構部分接口/代碼展示感受全部代碼 FastAPI學習記錄 fastapi已經學習有一段時間&#xff0c;今天抽時間簡單整理下。 官網介紹&#xff1a; FastAPI 是一個用于構建 API 的現代、快速&#xff08;高性能&#xff09;的 web 框架&#xff0c;使用 Py…

SpringBoot的配置文件以及日志設置

在使用SpringBoot開發的過程中我們通常會用到配置文件來設置配置信息 以及使用日志來進行記錄我們的操作&#xff0c;方便我們對錯誤的定位 配置文件的作用在于&#xff1a;設置端口&#xff0c;設置數據庫連接信息&#xff0c;設置日志等等 在SpringBoot中&#xff0c;配置…

Linux系統編程:通過System V共享內存實現進程間通信

目錄 一. 共享內存實現進程間通信的原理 二. 共享內存相關函數 2.1 共享內存的獲取 shmget / ftok 2.2 共享內存與進程地址空間相關聯 shmat 2.3 取消共享內存與進程地址空間的關聯 shmdt 2.4 刪除共享內存 shmctl 2.5 通信雙方創建共享內存代碼 三. 共享內存實現進程間…

承接各種設計

小弟985研究生畢業&#xff0c;目前攻讀讀博士&#xff0c;可做各種設計&#xff0c;包括但不限于Matlab 電力電子/電氣工程&#xff0c;matlab/simulink 電氣專業仿真MATLAB 電氣工程專業&#xff0c;matlab建模 電力電子&#xff0c;電氣工程&#xff0c;電力系統&#xff0c…

vue echarts macd指標 完整代碼

1 邏輯 給指定的series兩個對象 兩個對象有相同的xAxisIndex: 2,yAxisIndex: 2, 不同的data {name: "",type: "line",data: data1,xAxisIndex: 2,yAxisIndex: 2,},{name: "",type: "bar",data: data2,xAxisIndex: 2,yAxisIndex: 2,},…

Mac M2 Pro安裝使用Cocoapods

Mac Pro M2安裝使用Cocoapods 在新公司要做iOS開發&#xff0c;所以在新電腦上安裝Cocoapods 在升級gem&#xff0c;sudo gem update --system&#xff0c;和安裝cocoapods時都遇到如下的提示&#xff1a; ERROR: While executing gem ... (Errno::EPERM)Operation not per…

Linux下安裝nodejs

1、下載nodejs 點擊前往&#xff1a;Download | Node.js 2、解壓 tar -xvf node-v18.16.0-linux-x64.tar.xz mv node-v18.16.0-linux-x64/ /usr/local/nodejs 3、 建立軟鏈接 此時的bin文件夾中已經存在node以及npm&#xff0c;如果你進入到對應文件的中執行命令行一點問題…

現代C++:使用 shared_from_this 防止 this 提前被釋放

首先概括一下shared_from_this的作用&#xff1a;可以在類的成員函數中直接通過this得到指向當前所在對象的shared_ptr的智能指針&#xff0c;具體操作如下。 使用方法 設需要提供shared_from_this方法的類為C0定義為類&#xff0c;首先需要將C0定義為 std::enable_shared_fr…

mysql 02 數據庫的約束

為防止錯誤的數據被插入到數據表&#xff0c;MySQL中定義了一些維護數據庫完整性的規則&#xff1b;這些規則常稱為表的約束。常見約束如下&#xff1a; 主鍵約束 主鍵約束即primary key用于唯一的標識表中的每一行。被標識為主鍵的數據在表中是唯一的且其值不能為空。這點類似…

前后端分離------后端創建筆記(10)用戶修改

本文章轉載于【SpringBootVue】全網最簡單但實用的前后端分離項目實戰筆記 - 前端_大菜007的博客-CSDN博客 僅用于學習和討論&#xff0c;如有侵權請聯系 源碼&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…

Spring Boot實現第一次啟動時自動初始化數據庫流程詳解

隨著互聯網的發展項目中的業務功能越來越復雜&#xff0c;有一些基礎服務我們不可避免的會去調用一些第三方的接口或者公司內其他項目中提供的服務&#xff0c;但是遠程服務的健壯性和網絡穩定性都是不可控因素。 在測試階段可能沒有什么異常情況&#xff0c;但上線后可能會出…

https證書獲取的方法及好處

我們常說的https證書其實就是ssl證書&#xff0c;眼下為網站部署https證書是保障網站安全必不可少的一步。而https證書該如何獲取呢&#xff1f;下面就簡單介紹一下https證書獲取的方法。 https證書獲取途徑有兩種&#xff1a;自己簽發和由受信任的CA機構簽發。 自己給自己簽…

全國三網優惠話費充值接口開發指南

一、文檔綜述 近期想做項目的看過來~三網&#xff08;全國移動、聯通、電信&#xff09;話費、電費充值接口能夠實現將接口接入到小程序或者app上面&#xff0c;通過接口提交號碼和金額進行充值&#xff0c;可以幫助相關人員快速完成接口對接與聯調&#xff0c;平臺用戶可以通…

設計HTML5文本

網頁文本內容豐富、形式多樣&#xff0c;通過不同的版式顯示在頁面中&#xff0c;為用戶提供最直接、最豐富的信息。HTML5新增了很多文本標簽&#xff0c;它們都有特殊的語義&#xff0c;正確使用這些標簽&#xff0c;可以讓網頁文本更嚴謹、更符合語義。 1、通用文本 1.1、標…

算法競賽備賽之搜索與圖論訓練提升,暑期集訓營培訓

目錄 1.DFS和BFS 1.1.DFS深度優先搜索 1.2.BFS廣度優先搜索 2.樹與圖的遍歷&#xff1a;拓撲排序 3.最短路 3.1.迪杰斯特拉算法 3.2.貝爾曼算法 3.3.SPFA算法 3.4.多源匯最短路Floy算法 4.最小生成樹 4.1.普利姆算法 4.2.克魯斯卡爾算法 5.二分圖&#xff1a;染色法…

7. CSS(四)

目錄 一、浮動 &#xff08;一&#xff09;傳統網頁布局的三種方式 &#xff08;二&#xff09;標準流&#xff08;普通流/文檔流&#xff09; &#xff08;三&#xff09;為什么需要浮動&#xff1f; &#xff08;四&#xff09;什么是浮動 &#xff08;五&#xff09;浮…

OpenAI全球招外包大軍,手把手訓練ChatGPT取代碼農 ; 碼農:我自己「殺」自己

目錄 前言 OpenAI招了一千多名外包人員&#xff0c;訓練AI學會像人類一樣一步步思考。如果ChatGPT「學成歸來」&#xff0c;碼農恐怕真的危了&#xff1f; 碼農真的危了&#xff01; 當時OpenAI也說&#xff0c;ChatGPT最合適的定位&#xff0c;應該是編碼輔助工具。 用Cha…

常用的Elasticsearch查詢DSL

1.基本查詢 GET /index_name/_search {"query": {"match": {"dispatchClass": "1"}} }2.多條件查詢 GET /index_name/_search {"query": {"bool": {"must": [{"match": {"createUser&…