2014-11-17 61 views
0

我對二進制文件有點困惑,我知道的數據都是存儲在二進制文件的塊,並從我的知識,通過實驗我發現,如果我們有這樣的與成員變量的結構體:如何讀取二進制文件的塊(未知大小)?

struct student{ 
int Roll_No; 
char Name[10]; 
} 

然後,在用內容更新變量並將其保存在二進制文件中後,二進制文件爲14個字節,10個字節的char和4個int,因此如果我們在hexeditor中分析文件,則該文件有4個字節爲Roll_no保留並且爲Name保留10個字節,其中填充的內容被填充,其他的可以看作文件中的點,我的意思是如果我們創建一個類似上面的struct/class的程序,並且在將內容保存到文件後,文件的大小是和我們創建的結構一樣,我的意思是4的int和10的char,所以從我的知識,如果我創建一個新的圖像格式,例如。 (DOT).MyIMG,從我的程序,其是結構/類是這樣

struct MyIMG{ 
char Header[5]; 
int width, height; 
int Pixels[124000]; 
} 

然後我的程序將創建大小的新文件49613個字節或49個Kigabytes(這是頭5,+(加號)8的int高度和寬度,+(加上)4×124000的int像素),其中像素是4,8,100,或者任何它將寫入整個像素陣列的空白,所以爲什麼這個效果不能在任何大軟件如MSpaint,Adobe公司的Photoshop,他們做什麼,這使得他們的程序編寫的文件的大小取決於存儲像素不是空白陣列...

編輯:我現在編輯我的問題,並明確定義我的問題,請幫助我,提前致謝!

+1

這些點並不意味着「無」,它們的意思是「不可打印的字符」。 –

+5

是......這是一句話嗎? – etheranger

+0

我知道那些是不可打印的ascii字符,因爲十六進制編輯器顯示文件的十六進制值的一側,另一側顯示爲ascii,並且我沒有用C++的視圖來表示,因爲在讀入內存之後(在一個變量中,例如。Char)字符串在字符串結束的地方自動終止,但是如何處理大小不等的文件,我不知道,你明白我了? – Rishabh

回答

1

寫入文件的代碼必須選擇它自己的格式。例如,寫你student結構時文件,你可以這樣說:

size_t name_len = strlen(my_student.Name); 
my_ofstream.write((const char*)&my_student, sizeof my_student - sizeof my_student.Name + name_len + 1); 

這會接着寫名字直到幷包括第一個0/NULL字符的二進制文件。當讀取文件時,程序可以讀取ifstream中的一個數據塊,然後 - 知道student存儲在某個偏移量處,使用strlen()對傳入數據的.Name部分進行恢復,部分是因爲它只能複製必要的數據爲student對象,也知道從哪裏開始從輸入流中解析下一個數據項:

char buffer[32768]; 
student my_student; 
if (my_ifstream.read(buffer, sizeof buffer) && my_ifstream.gcount() > 5) 
{ 
    // check for NUL without risking reading buffer[.gcount()] 
    size_t pre_name_len = std::offsetof(student, name); 
    const char* p_name = buffer + pre_name_len; 
    const char* p_nul = strnchr(p_name, 
           std::min(10, my_ifstream.gcount() - pre_name_len), 
           '\0'); 
    if (p_nul == nullptr || *p_nul != '\0') 
     throw std::runtime_error("file didn't contain complete student record"); 
    memcpy(my_student, buffer, p_nul - buffer + 1); 

    // keep parsing input from p_nul + 1, not going past .gcount() 
} 

正如你所看到的 - 這是一個有點痛,以掃描單個NULL,同時保持追蹤從文件中讀取的數據量,以便在發生損壞的輸入文件時不會崩潰....

對於初學者,它可能是最簡單和更強大的瞭解boost serialisation library,它抽象了大部分低級別 - 有人會說C風格 - I/O,鑄造和偏移量計算,爲您提供一個更乾淨的邏輯接口。

2

像.png和.bmp這樣的文件格式具有特定的格式。文件格式可以指定一個字節佈局(例如4個字節的寬度,4個字節的高度,2MB的RGBA像素數據,或其他),或者格式可以給你關於各種對象大小的信息。

例如,TIFF文件將指定文件內特定字節偏移處有數字標記。那些標籤包含有關圖像數據的大小,位置和格式的信息。因此,您可能會有一個固定大小的標題,表示「有從第100個字節開始的標記列表,並且它包含40個標記。」這些標籤每個都是固定的大小(比如16字節),所以你應該知道從字節100開始讀取40個16字節的塊。然後標籤將包含諸如圖像數據的開始的字節偏移量,像素中有多少字節以及有多少像素的信息。由此,您可以在不事先知道整個格式是什麼的情況下閱讀數據。

相關問題