解讀C++編程的相關文件操作
C++文件的概念
迄今為止,我們討論的輸入輸出是以系統(tǒng)指定的標準設備(輸入設備為鍵盤,輸出設備為顯示器)為對象的。在實際應用中,常以磁盤文件作為對象。即從磁盤文件讀取數(shù)據(jù),將數(shù)據(jù)輸出到磁盤文件。磁盤是計算機的外部存儲器,它能夠長期保留信息,能讀能寫,可以刷新重寫,方便攜帶,因而得到廣泛使用。
文件(file)是程序設計中一個重要的概念。所謂“文件”,一般指存儲在外部介質(zhì)上數(shù)據(jù)的集合。一批數(shù)據(jù)是以文件的形式存放在外部介質(zhì)(如磁盤、光盤和U盤)上的。操 作系統(tǒng)是以文件為單位對數(shù)據(jù)進行管理的,也就是說,如果想找存在外部介質(zhì)上的數(shù)據(jù), 必須先按文件名找到所指定的文件,然后再從該文件中讀取數(shù)據(jù)。要向外部介質(zhì)上存儲數(shù)據(jù)也必須先建立一個文件(以文件名標識),才能向它輸出數(shù)據(jù)。
外存文件包括磁盤文件、光盤文件和U盤文件。目前使用最廣泛的是磁盤文件,為敘述方便,教程中凡用到外存文件的地方均以磁盤文件來代表,在程序中對光盤文件和U盤文件的使用方法與磁盤文件相同。
對用戶來說,常用到的文件有兩大類,一類是程序文件(program file),如C++的源程序文件(.cpp)、目標文件(.obj)、可執(zhí)行文件(.exe)等。一類是數(shù)據(jù)文件(data file), 在程序運行時,常常需要將一些數(shù)據(jù)(運行的最終結果或中間數(shù)據(jù))輸出到磁盤上存放起來,以后需要時再從磁盤中輸入到計算機內(nèi)存。這種磁盤文件就是數(shù)據(jù)文件。程序中的輸入和輸出的對象就是數(shù)據(jù)文件。
根據(jù)文件中數(shù)據(jù)的組織形式,可分為ASCII文件和二進制文件。ASCII文件又稱文本(text)文件或字符文件,它的每一個字節(jié)放一個ASCII代碼,代表一個字符。二進制文件又稱內(nèi)部格式文件或字節(jié)文件,是把內(nèi)存中的數(shù)據(jù)按其在內(nèi)存中的存儲形式原樣輸出到磁盤上存放。
對于字符信息,在內(nèi)存中是以ASCII代碼形式存放的,因此,無論用ASCII文件輸出還是用二進制文件輸出,其數(shù)據(jù)形式是一樣的。但是對于數(shù)值數(shù)據(jù),二者是不同的。例如有一個長整數(shù)100000,在內(nèi)存中占4個字節(jié),如果按內(nèi)部格式直接輸出,在磁盤文件中占 4個字節(jié),如果將它轉換為ASCII碼形式輸出,則要占6個字節(jié)。
用ASCII碼形式輸出的數(shù)據(jù)是與字符一一對應的,一個字節(jié)代表一個字符,可以直接在屏幕上顯示或打印出來。這種方式使用方便,比較直觀,便于閱讀,便于對字符逐個進行輸入輸出。但一般占存儲空間較多,而且要花費轉換時間(二進制形式與ASCII碼間的轉換)。用內(nèi)部格式(二進制形式)輸出數(shù)值,可以節(jié)省外存空間,而且不需要轉換時間,但一個字節(jié)并不對應一個字符,不能直接顯示文件中的內(nèi)容。如果在程序運行過程中有些中間結果數(shù)據(jù)暫時保存在磁盤文件中,以后又需要輸入到內(nèi)存的,這時用二進制文件保存是最合適的。如果是為了能顯示和打印以供閱讀,則應按ASCII碼形式輸出。此時得到的是ASCII文件,它的內(nèi)容可以直接在顯示屏上觀看。
C++提供了低級的I/O功能和高級的I/O功能。高級的I/O功能是把若干個字節(jié)組合為一個有意義的單位(如整數(shù)、單精度數(shù)、雙精度數(shù)、字符串或用戶自定義的類型的數(shù)據(jù)),然后以ASCII字符形式輸入和輸出。例如將數(shù)據(jù)從內(nèi)存送到顯示器輸出,就屬于高級I/O功能,先將內(nèi)存中的數(shù)據(jù)轉換為ASCII字符,然后分別按整數(shù)、單精度數(shù)、雙精度數(shù)等形式輸出。這種面向類型的輸入輸出在程序中用得很普遍,用戶感到方便。但在傳輸大容量的文件時由于數(shù)據(jù)格式轉換,速度較慢,效率不高。
所謂低級的I/O功能是以字節(jié)為單位輸入和輸出的,在輸入和輸出時不進行數(shù)據(jù)格式的轉換。這種輸入輸出是以二進制形式進行的。通常用來在內(nèi)存和設備之間傳輸一批字節(jié)。這種輸入輸出速度快、效率高,一般大容量的文件傳輸用無格式轉換的I/O。但使用時會感到不大方便。
C++文件的打開與關閉
這里講一下如何打開和關閉磁盤上的文件,其他外設(U盤、光盤等)上的文件與此相同。
打開文件
所謂打開(open)文件是一種形象的說法,如同打開房門就可以進入房間活動一樣。 打開文件是指在文件讀寫之前做必要的準備工作,包括:
為文件流對象和指定的磁盤文件建立關聯(lián),以便使文件流流向指定的磁盤文件。
指定文件的工作方式,如,該文件是作為輸入文件還是輸出文件,是ASCII文件還是二進制文件等。
以上工作可以通過兩種不同的方法實現(xiàn)。
1) 調(diào)用文件流的成員函數(shù)open。如
ofstream outfile; //定義ofstream類(輸出文件流類)對象outfile outfile.open("f1.dat",ios::out); //使文件流與f1.dat文件建立關聯(lián)
第2行是調(diào)用輸出文件流的成員函數(shù)open打開磁盤文件f1.dat,并指定它為輸出文件, 文件流對象outfile將向磁盤文件f1.dat輸出數(shù)據(jù)。ios::out是I/O模式的一種,表示以輸出方式打開一個文件。或者簡單地說,此時f1.dat是一個輸出文件,接收從內(nèi)存輸出的數(shù)據(jù)。
調(diào)用成員函數(shù)open的一般形式為:
文件流對象.open(磁盤文件名, 輸入輸出方式);
磁盤文件名可以包括路徑,如"c:\new\\f1.dat",如缺省路徑,則默認為當前目錄下的文件。
2) 在定義文件流對象時指定參數(shù)
在聲明文件流類時定義了帶參數(shù)的構造函數(shù),其中包含了打開磁盤文件的功能。因此,可以在定義文件流對象時指定參數(shù),調(diào)用文件流類的構造函數(shù)來實現(xiàn)打開文件的功能。如
ostream outfile("f1.dat",ios::out);
一般多用此形式,比較方便。作用與open函數(shù)相同。
輸入輸出方式是在ios類中定義的,它們是枚舉常量,有多種選擇,見表
幾點說明:
1) 新版本的I/O類庫中不提供ios::nocreate和ios::noreplace。
2) 每一個打開的文件都有一個文件指針,該指針的初始位置由I/O方式指定,每次讀寫都從文件指針的當前位置開始。每讀入一個字節(jié),指針就后移一個字節(jié)。當文件指針移到最后,就會遇到文件結束EOF(文件結束符也占一個字節(jié),其值為-1),此時流對象的成員函數(shù)eof的值為非0值(一般設為1),表示文件結束了。
3) 可以用“位或”運算符“|”對輸入輸出方式進行組合,如表13.6中最后3行所示那樣。還可以舉出下面一些例子:
ios::in | ios:: noreplace //打開一個輸入文件,若文件不存在則返回打開失敗的信息 ios::app | ios::nocreate //打開一個輸出文件,在文件尾接著寫數(shù)據(jù),若文件不存在,則返回打開失敗的信息 ios::out l ios::noreplace //打開一個新文件作為輸出文件,如果文件已存在則返回打開失敗的信息 ios::in l ios::out I ios::binary //打開一個二進制文件,可讀可寫
但不能組合互相排斥的方式,如 ios::nocreate l ios::noreplace。
4) 如果打開操作失敗,open函數(shù)的返回值為0(假),如果是用調(diào)用構造函數(shù)的方式打開文件的,則流對象的值為0。可以據(jù)此測試打開是否成功。如
if(outfile.open("f1.bat", ios::app) ==0) cout <<"open error";
或
if( !outfile.open("f1.bat", ios::app) ) cout <<"open error";
關閉磁盤文件
在對已打開的磁盤文件的讀寫操作完成后,應關閉該文件。關閉文件用成員函數(shù)close。如
outfile.close( ); //將輸出文件流所關聯(lián)的磁盤文件關閉
所謂關閉,實際上是解除該磁盤文件與文件流的關聯(lián),原來設置的工作方式也失效,這樣,就不能再通過文件流對該文件進行輸入或輸出。此時可以將文件流與其他磁盤文件建立關聯(lián),通過文件流對新的文件進行輸入或輸出。如
outfile.open("f2.dat",ios::app|ios::nocreate);
此時文件流outfile與f2.dat建立關聯(lián),并指定了f2.dat的工作方式。
相關文章
vsCode配置import@路徑提示的實現(xiàn)步驟
在導入文件設置路徑的時候方便了很多,本文主要介紹了vsCode配置import@路徑提示的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下2023-08-08C++?opencv利用grabCut算法實現(xiàn)摳圖示例
這篇文章主要為大家介紹了C++?opencv利用grabCut算法實現(xiàn)摳圖的代碼示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05openCV4.1.1+VS2019環(huán)境配置詳解
這篇文章主要介紹了openCV4.1.1+VS2019環(huán)境配置詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08基于C++浮點數(shù)(float、double)類型數(shù)據(jù)比較與轉換的詳解
本篇文章是對C++中浮點數(shù)(float、double)類型數(shù)據(jù)比較與轉換進行了詳細的分析介紹,需要的朋友參考下2013-05-05C++實現(xiàn)LeetCode(160.求兩個鏈表的交點)
這篇文章主要介紹了C++實現(xiàn)LeetCode(160.求兩個鏈表的交點),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07