使用者:Arnie97/Off Topic
外觀
數據對象的內部表示(變量)
數據在內存中以不同的方式(數據結構)儲存著。這些數據結構當中有順序的(例如線性表的數組形式),也有非順序的(例如線性表的鍊表形式)。
數據對象的外部表示(文件)
為了將數據,尤其是非順序的數據:
- 保存於外存(硬碟、光碟、快閃記憶體等)的某個文件中以備後用
- 通過網絡等方式共享給另一台計算機
- 通過串口等方式傳送至圖形計算器等設備
我們需要將數據編碼為字符串(字節流)方能儲存或傳輸,這一編碼過程稱為序列化(Serialization)。
變量的類型系統:靜態類型與動態類型
變量是代指數據的名稱、符號。
- 在 C++、Java 等語言中,每個變量均對應一個特定的數據類型,使用前必須聲明每個變量的數據類型,這樣的類型系統稱為靜態類型。
- 在 Haskell 等語言中,雖然很多情況下不需手動聲明變量的數據類型,而是通過計算機的自動推導來確定數據類型,但每個變量均有特定的類型——類似 C++ 11 中使用
auto的情形——因此同樣屬於靜態類型。 - 在 Python、JavaScript 等語言中,類型依附於變量中儲存的數據本身,數據有類型而變量無類型,這樣的類型系統稱為動態類型。
文件的類型判定:擴展名與特徵簽名
類比變量,文件名(和路徑)是代指文件的符號。對於文件來說,同樣有數種不同的方式來記錄它的類型,其中就包括:
- 文件名稱的某個特定部分指示一個文件的類型——通常是最後一個小數點後的部分,也就是擴展名(Extension)。
- 文件內容的某個特定部分,即特徵簽名(File Signature)指示一個文件的類型——通常是最前面的部分,也就是頭部(Header)。
擴展名最早在 CP/M 作業系統中被採用,而後又隨一脈相承的 DOS 和 Windows 得到了推廣;特徵簽名則在 Unix 中被廣泛應用,而後又被 Linux 等作業系統所繼承下來。由於兩類作業系統均得到了廣泛的應用,現實中兩種方式常常共存:
| 文件類型 | 擴展名 | 特徵簽名[1] |
|---|---|---|
| PDF 文檔 | %PDF
| |
| ZIP 壓縮文件 | zip docx pptx xlsx 等 | PK(設計者 Phil Katz)
|
| RAR 壓縮文件 | rar | Rar!
|
| CAB 壓縮文件 | cab | MSCF(Microsoft Cabinet File)
|
| MZ 可執行文件 | com exe
exe dll sys ocx cpl scr 等 |
MZ(設計者 Mark Zbikowski)
(為向下兼容 DOS,PE 文件頭部與之相同) |
| ELF 可執行文件 | 無 | \x7F E L F
|
| PNG 圖片 | png | \x89 P N G
|
| GIF 圖片 | gif | GIF89a 或 GIF87a
|
| JPEG 圖片 | jpg jpeg | 以 \xFF \xD8開始,\xFF \xD9 結束
|
| Midi 音軌 | midi | MThd(MIDI Track header)
|
| Java 字節碼 | class | \xCA \xFE \xBA \xBE,即十六進制 CAFEBABE
|
從上面的例子中可以看出,既有一個擴展名對應多種特徵簽名的情況(如 GIF 文件),也有多種擴展名對應單一特徵簽名的情況(如 PE 文件)。當擴展名和特徵簽名共存時,有時會結合兩種因素來決定文件如何解析,更多時候則只選擇其中的主要因素來判斷文件的類型。例如,將 JPEG 圖片的擴展名更改為 png 仍能用多數圖片查看器正常打開,說明這些軟體僅通過文件內容中的特徵簽名來判斷文件的格式,擴展名無關緊要。