RTF 檔案格式
Rich Text Format,一種跨平台的格式化文字文件格式。
- MIME 類型
- application/rtf
- 副檔名
- .rtf
- 分類
- 文件
Magic number(檔案簽章)
| 0x00000000 | 7B5C72746631 | {\rtf1 | '{\rtf1' header |
關於 RTF 格式
RTF 整份文件都是可列印的 ASCII:大括號開關群組,反斜線開頭的控制字帶著格式資訊,其餘就是字面文字。這讓它成為唯一一種你可以在文字編輯器裡直接讀、直接 diff、直接修好的文書處理格式,也是唯一一種被貼進郵件軟體還活得下來的格式。代價是體積和保真度——含圖片的 RTF 大得誇張,因為每張圖的每個位元組都得寫成十六進位數字。
檔頭結構,一個位元組一個位元組看
| 位移 | 長度 | 欄位 | 意義 |
|---|---|---|---|
| 0 | 1 | Opening group brace | 位元組 7B,也就是 '{'。整份文件是一個群組,所以這個大括號的配對對象就是檔案的最後一個位元組。群組會巢狀,而括號沒配對是 RTF 檔壞掉最常見的單一原因。 |
| 1 | 4 | \rtf control word | 4 個位元組 5C 72 74 66。控制字是一個反斜線接小寫字母,後面可帶一個數值參數;這一個指名格式本身,而且必須是最外層群組裡的第一個東西。 |
| 5 | 1 | Version digit | \rtf 的數值參數,而且所有發行過的 RTF 這裡都是單一個 ASCII 字元 '1'。規格都走到 1.9.1 了,這個數字從來沒有加過,所以它標示的是格式而不是版本。 |
| 6 | variable | Character set control word | 規格要求字元集必須緊接在版本後面。你幾乎永遠只會看到 \ansi,佔 5 個位元組;\mac、\pc、\pca 是舊的替代選項,長度較短,會讓底下每個位移往前移。 |
| 11 | variable | \ansicpg code page | 只有在字元集控制字是 5 個位元組的 \ansi 時,才剛好落在這個位移。它的參數是文件內容所使用的 Windows 字碼頁——1252 是西歐、936 是簡體中文、932 是日文。超出該字碼頁的字元會改用 \'hh 或 \uNNNN? 逸出。 |
| variable | variable | \deff, \fonttbl and \colortbl | 字碼頁後面接的是預設字型索引,然後是字型表群組 {\fonttbl ...},通常還有一個色彩表 {\colortbl ...}。它們的位移取決於上面所有東西,但它們一定是群組、一定在文件本文之前,所以把前面幾百個位元組 dump 出來,就能看到明碼 ASCII 的字型名稱。 |
| -1 | 1 | Closing group brace | 位元組 7D,也就是 '}',關掉位移 0 開的那個群組。有些寫入端會在後面補一組 CR LF。如果最後一個非空白位元組不是右大括號,這個檔案就是被截斷了——而且和多數格式不同,你常常可以自己手動把缺的括號補回去修好它。 |
怎麼跟長得像的格式分開
| 容易搞混的 | 怎麼分 |
|---|---|
| Word 文件(docx) | 位元組層級一點都不像——'{\rtf1' 對上 50 4B 03 04——但一般人講「不是 .doc 的 Word 檔」時,指的就是這兩種。Word 兩種都讀也都寫,而且 .docx 改名成 .rtf 照樣在 Word 裡打得開,因為 Word 是看位元組的。RTF 不帶修訂歷程、不帶註解討論串、也不能內嵌字型,所以「另存成 RTF」是一種刻意把文件剝乾淨的手法。 |
| OLE2 / CFB | 這一對才是真的會搞混,因為 '.doc' 最後可能是這兩種的任一種。真正的 Word 97 二進位文件是 Compound File Binary 容器,開頭 D0 CF 11 E0;但以 .doc 散布出去的檔案裡,有非常多其實是 RTF,因為 RTF 到哪都打得開,而那個副檔名大家比較熟。看位移 0,不要看副檔名:'{\rtf1' 沒有模稜兩可的空間。 |
| HTML | 兩者都是由可讀 ASCII 組成的標記語言,也都是你複製格式化文字時剪貼簿會提供的東西——Windows 會同時放上 RTF 和 HTML。位移 0 一眼就分得出來,但實務上真正的差別是 RTF 完全沒有外部參照:沒有連結的樣式表、沒有遠端圖片,全部都是內嵌的,這也是為什麼陌生人寄來的檔案,收 RTF 比收 HTML 安全。 |
| 純文字(帶 BOM 的 UTF-8) | RTF 嚴格說來就是純 ASCII 文字,所以只檢查「位元組是否可列印」的粗糙偵測器會把它判成純文字——而文字編輯器也真的打得開,只是會把標記全攤在你面前。分辨的方法是開頭那 6 個位元組;另外要注意 RTF 不允許帶 UTF-8 BOM,因為檔案必須以大括號起頭,所以位移 0 出現 EF BB BF 就代表這個檔案被動過手腳。 |
常見的壞法
- 大括號沒配對。因為群組會巢狀、控制字會從外層群組繼承,少一個 '}' 就等於那個群組裡設定的每一項格式全部漏到文件剩下的部分。看得到的症狀是:檔案打得開,後半段字型不對或整段變粗體,而且從頭到尾沒有任何錯誤訊息。
- 字碼頁設錯。\ansicpg 寫 1252,但內容其實是用 936 寫的話,每個非 ASCII 字元都會變亂碼。檔案一個位元組都沒壞、文件結構也完好無缺——錯的只是位移 11 那一個數字,把它改對,整份文件就復原了。
- 被截斷。被切掉的 RTF 在多數文書軟體裡照樣打得開,它們就把解析到的部分算繪出來,然後自己把沒關的群組收掉。這種寬容是個陷阱:文件看起來很完整,最後幾頁卻無聲無息地不見了。檢查最後一個非空白位元組是不是 '}'。
- 字面文字裡有沒逸出的反斜線。特殊字元只有反斜線、大括號和那幾種逸出序列,所以寫入端忘了逸出一個字面的 '\' 或 '{',就會把使用者的文字變成控制字。結果是那段文字從算繪結果裡消失,但在 hex dump 裡看得一清二楚。
- 換行字元轉換,這次難得無害。RTF 會忽略控制字以外的 CR 與 LF,所以那個會毀掉 PNG 或 ZIP 的文字模式傳輸,對 RTF 完全沒影響。它是極少數真的能撐過 ASCII 模式 FTP 的準二進位格式。
這個格式現在還在用嗎
RTF 是備援格式,而且到現在還是最好用的那個備援。沒有人會選它來寫東西,但「給我一份有格式、到哪都打得開的檔案」的可靠答案還是它,因為 1987 年之後寫出來的每一套文書軟體都讀得懂,而且都不用外掛。它特別活躍在三個地方:Windows 和 macOS 剪貼簿的格式化文字類型,所以應用程式之間每一次帶樣式的複製貼上,本質上都走了一趟 RTF;不能綁定單一廠商的法務與政府系統的匯出格式;以及來路不明文件的安全收件格式,因為 RTF 沒有巨集、沒有指令碼、也沒有外部參照。微軟在 2008 年的 1.9.1 版之後就停止開發規格,Word 自己的 RTF 轉換器也已經標為淘汰,所以它是被凍住而不是還在演進。要做新東西,.docx 保真度高得多、體積只有零頭——放了幾張照片的 RTF 動輒幾十 MB,因為圖片是以 ASCII 十六進位存的,體積先翻倍,而且完全沒有壓縮。
在這個站上打開 RTF 檔
這些全部在你的瀏覽器裡跑,檔案不會離開你的電腦。
相關格式
容易和 RTF 搞混的格式,可以比對它們的開頭位元組。
| 格式 | 開頭位元組 | 副檔名 |
|---|---|---|
| Word 文件(docx) | 50 4B 03 04 | .docx |
| OLE2 / CFB | D0 CF 11 E0 A1 B1 | .doc |
| 25 50 44 46 2D |