自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C++中隨機存取文件的處理

開發(fā) 后端
在本文中,我們所講的是怎樣使用C++中的隨機存取文件。除了最簡單的應(yīng)用程序以外,大多數(shù)程序都需要讀寫文件?;蛟S只是為了讀取一個配置文件,一個文本解析器或更為復(fù)雜的什么東西。

和許多的C++程序一樣,有些人更喜歡用原先的C語言方式處理問題,如果你恰好也是這些人中的一員,就應(yīng)該學(xué)習(xí)一下這篇文章。

基本的文件操作有

◆fopen——打開文件,指定文件以怎樣的方式打開(讀/寫)以及類型(二進制/文本)

◆fclose——關(guān)閉已經(jīng)打開的文件

◆fread——讀取文件

◆fwrite——寫文件

◆fseek/fsetpos——將文件指示器轉(zhuǎn)移到文件中的某一地方

◆ftell/fgetpos——可以告訴你文件指示器所在的位置

文件有兩種基本類型:文本和二進制。在這兩者之中,通常二進制類型是較容易解決的。由于在文本中處理隨機存取并不常用,我們會在本文中重點關(guān)注二進制文件的處理。上面列出的操作中的前四項可用于文本文件和隨機存取文件。后面的兩項則僅用于隨機存取。

隨機存取意味著我們可以在文件的任意部分之間進行切換,且可以從中讀寫數(shù)據(jù)而不需要通讀整篇文件。

二進制文件

二進制文件是任意長度的文件,它保存有從0到0xff(0到255)不等的字節(jié)值。這些字節(jié)在二進制文件中沒有任何意義,與此不同的是,在文本文件中,值為13就意味著回車,10意味著換行,26意味著文件結(jié)束,而讀取文本文件的軟件要能夠解決這些問題。

在現(xiàn)在的術(shù)語中,我們將二進制文件稱為包含了字節(jié)的字符流,大多數(shù)語言傾向于將其理解為字符流而不是文件。重要的部分是數(shù)據(jù)流本身而不是其來源。在C語言中,你能從文件或數(shù)據(jù)流方面來考慮數(shù)據(jù)?;蛘?,你可以將其理解為一組長的數(shù)組。通過隨機存取,你可以讀寫數(shù)組的任意部分。

      例一:
// ex1.c : Defines the entry point for the console application.

//

#include < stdio.h>

#include < string.h>

#include < windows.h>

int FileSuccess(FILE * handle,const char * reason, const char * path) {

OutputDebugString( reason );

OutputDebugString( path );

OutputDebugString(" Result : ");

if (handle==0)

{

OutputDebugString("Failed");

return 0;

}

else

{

OutputDebugString("Suceeded");

return 1;

}

}

int main(int argc, char * argv[])

{

const char * filename="test.txt";

const char * mytext="Once upon a time there were three bears.";

int byteswritten=0;

FILE * ft= fopen(filename, "wb");

if (FileSuccess(ft,"Opening File: ", filename)) {

fwrite(mytext,sizeof(char),strlen(mytext), ft);

fclose( ft );

}

printf("len of mytext = %i ",strlen(mytext));

return 0;

}
 

這段代碼顯示了一個簡單的打開待寫的二進制文件,文本字符(char*)會寫入該文件。通常你會使用文本文件但是筆者想證明你可以向二進制文件寫入文本。

     // ex1.c

     #include < stdio.h>

     #include < string.h>

     int main(int argc, char * argv[])

    {

     const char * filename="test.txt";

     const char * mytext="Once upon a time there were three bears.";

     int byteswritten=0;

     FILE * ft= fopen(filename, "wb") ;

     if (ft) {

     fwrite(mytext,sizeof(char),strlen(mytext), ft) ;

     fclose( ft ) ;

     }

      printf("len of mytext = %i ",strlen(mytext)) ;

     return 0;

     }
 

例一的作用

這個例子打開了一個待寫的二進制文件。FILE*變量從fopen()調(diào)用中返回。如果這一操作失敗那么它會返回為0。

Fopen()命令試圖打開指定的文件,在這個案例中則是位于相同文件夾的test.txt。記住,如果文件包含一個路徑那么所有的退格必須重疊。“c:\folder\test.txt”是錯誤的,你必須使用“c:\\folder\\test.txt”。

由于文件樣式是wb,我們正準(zhǔn)備寫入二進制文件。如果文件不存在則系統(tǒng)會創(chuàng)建一個文件,如果存在,則里面的內(nèi)容都會被刪除。如果調(diào)用fopen失敗了,或許由于文件被打開了,或者其名稱包括無效字符又或者一個無效路徑那么fopen會返回0值。

雖然你可以只檢查ft是否為0(值為0則成功),但是筆者還是添加了一個FileSuccess()函數(shù)來確保這一操作。在窗口中,它會顯示調(diào)用是否成功以及文件名稱。如果你失敗了則可能需要修復(fù)。注意在Windows中一般沒有多少輸出文本可供系統(tǒng)調(diào)試器使用,

 fwrite(mytext,sizeof(char),strlen(mytext), ft) ; fwrite()調(diào)用輸出了指定文本。第二,三個參數(shù)分別是字符的大小和字符串的長度。它們兩個都是被size_t定義了。注意有了二進制文件后,即便你正在向文件中寫入(char*)字符串,它也沒有任何附加換行字符。如果你想要這些字符,你必須明確將這些字符包含到字符串中。

讀寫文件

打開一個文件的時候,必須指定打開的方式。這意味著如果你打算要為文件附加?xùn)|西,那么是否要創(chuàng)建新文件并對其進行覆蓋?它是文本文件還是二進制文件呢?是要讀取文件還是要寫文件呢?這樣要通過使用一個或更多的文件模式分類符來完成,文件模式分類符是一些單獨的字母“r”,“b”,“w”,“a”和+?!皉”意思是打開文件以便讀取。如果文件不存在或找不到文件這一操作會失敗?!皐”意思是待寫方式或空文件方式打開文件。如果文件存在,則文件內(nèi)容會被損壞?!癮”表示打開文件,并準(zhǔn)備從文件末端寫入而不需要在寫入新數(shù)據(jù)前刪除EOF標(biāo)記;如果不存在該文件則首先會創(chuàng)建一個文件。向文件模型添加+會創(chuàng)建下列三種新模型:

“r+”打開文件等待讀取或?qū)懭??!皐+”以空文件方式打開文件等待讀取或?qū)懭?。如果文件存在,則文件內(nèi)容會被損毀。

“a+”打開文件等待讀取或添加,添加的操作包括新數(shù)據(jù)寫入前EOF標(biāo)記的移除,以及寫入完成后EOF標(biāo)記的保存,如果文件不存在則先要創(chuàng)建文件。

下面的列表顯示了字碼組合包括文本的和二進制文件的。通常你可以選擇從文本文件中讀取或?qū)懭胛募?,但是不要兩者同時使用。

就二進制文件而言,你可以選擇對相同文件進行讀取和寫入的操作。列表告訴了我們可以用字碼進行哪些操作。

       Mode Type of file Read Write Create Truncate 
r text Read

rb+ binary Read

r+ text Read Write

r+b binary Read Write

rb+ binary Read Write

w text Write Create Truncate

wb binary Write Create Truncate

w+ text Read Write Create Truncate

w+b binary Read Write Create Truncate

wb+ binary Read Write Create Truncate

a text Write Create

ab binary Write Create

a+ text Read Write Create

a+b binary Write Create

ab+ binary Write Create
 

就筆者的經(jīng)驗來看,除非你剛剛創(chuàng)建完文件或讀取完文件,否則你通過使用“w+b”只能僥幸成功。

還有一些情況允許其他字母存在。例如微軟運行“t”代表文本模式,“c”用于認(rèn)可,“n”用于非認(rèn)可,“S”為順序存取優(yōu)化緩沖,“R”代表隨機存取,“T”代表臨時性而“D”用于 刪除/臨時性保存。

使用二進制文件的主要原因是可以獲得靈活性;你可以讀取或?qū)懭胛募娜我獠糠?。文本文件只能讓你按照順序讀取或?qū)懭搿,F(xiàn)在隨著SQLite或MySQL數(shù)據(jù)庫的普及,在二進制文件中使用隨機存取的需要減少了。從某種意義上說,隨機存取文件記錄有點老土了,但是仍然還是有用的。

筆者在數(shù)據(jù)庫普及之前就使用過基于隨機存取文件的多種數(shù)據(jù)處理方案。例如,在小文件中,筆者使用的是 索引/數(shù)據(jù) 文件模式。該模式包括兩個文件。一個是數(shù)據(jù)文件,它保存了一些長短不一的記錄。另一種文件是索引文件,這樣的文件擁有同樣的記錄作為數(shù)據(jù)文件。但是在索引文件中每個記錄的長度相同而且都由兩個適合結(jié)構(gòu)的部分組成。

struct {??fpos_t pos;??int size; } indexrec; 

類型fpos_t是由fsetpos()和fgetpos()定義和使用的執(zhí)行。這些是fseek和ftell更新的版本且更有助于創(chuàng)建書簽。如果你正在計算文件聞之且需要設(shè)定文件那么你應(yīng)該使用fseek(),另外ftell()也可以給你int的當(dāng)前位置。

在實際操作中,fpos_t可能只是一個int但是你應(yīng)該使用fpos_t類型。它保存了當(dāng)前文件指示器的副本。這是隨機存取文件的屬性,它表明了下一次讀取或?qū)懭氲奈恢?。它的粒度為一,因此你可以將其放在文件的任意位置?/P>

【編輯推薦】

  1. C++、Java與C#的命名規(guī)范總結(jié)
  2. 在C++中使用Lambda函數(shù)提高代碼性能
  3. 給C++初學(xué)者的50條建議
責(zé)任編輯:彭凡 來源: IT專家網(wǎng)
相關(guān)推薦

2009-12-16 10:41:37

Ruby隨機存取文件

2010-05-05 10:20:43

Java

2010-01-21 09:34:57

C++語法

2010-01-27 16:05:06

C++堆棧

2023-12-04 09:37:00

C++靜態(tài)變量

2010-01-21 14:07:14

CC++聲明

2018-01-29 08:44:14

2010-01-20 10:19:55

C++數(shù)組

2010-01-21 13:33:44

C++基類

2010-01-25 10:25:19

C++變量

2010-01-28 16:31:54

C++類型

2010-01-27 17:16:52

C++構(gòu)造函數(shù)

2020-08-21 13:20:36

C++If ElseLinux

2010-01-26 10:42:26

C++函數(shù)

2019-01-04 10:41:07

系統(tǒng)內(nèi)存SRAM

2024-01-25 11:32:21

2015-12-28 11:25:51

C++異常處理機制

2024-05-31 12:50:49

C++編程NaN

2011-04-11 11:09:50

this指針

2010-01-26 14:35:11

C++關(guān)鍵字
點贊
收藏

51CTO技術(shù)棧公眾號