將檔案轉換為不含 BOM 的 UTF-8,代表產生一個 UTF-8 位元組串流,其開頭正好是文本的第一個字元,而非三個位元組的標記 EF BB BF。最安全的做法是先識別出實際寫入該檔案的編碼,以嚴格驗證的方式解碼這些位元組,再透過一個不會預先加上 BOM、且符合標準的 UTF-8 編碼器重新編碼。UTF-8 Converter 正是依循這個流程運作:它會讀取本機的文字檔、以你選擇的編碼進行解碼、預覽非 ASCII 的內容,並下載一個位元組從第一個解碼字元開始的新檔案。由於 WHATWG 編碼解碼器與瀏覽器的 File API 都是在記憶體中完成工作,原始位元組從未離開你的裝置,這在檔案包含姓名、內部備註,或不想上傳到任何地方的程式碼時格外重要。下載的檔案會以純文字媒體類型產出,並在原始檔名後附加 -utf8 作為新檔名。

convert to utf 8 without bom
透過選擇來源編碼,將檔案轉換為不含 BOM 的 UTF-8

為什麼 UTF-8 BOM 會干擾實際的工作流程

UTF-8 位元組順序標記就是 EF BB BF 這段位元組序列。這個標記的存在,是因為 Unicode 允許 UTF-8 檔案帶有 BOM,以與 UTF-16 對稱,但對一個 8 位元編碼而言它並不帶來任何有用的資訊:UTF-8 並沒有位元組順序需要標示,而且首個碼點無需前綴就能明確識別。部分 Windows 編輯器在使用者選擇「另存為 UTF-8」時,無論如何都會加上 BOM,這正是為何一個原本乾淨的文字檔,會突然在那些從未預期開頭有三個隱形位元組的工具中失敗的原因。

PHP 會拒絕原始檔案開頭的 BOM,因為它會被視為輸出內容;而以嚴格 UTF-8 為基礎所建立的 SQL 解析器,會將它讀成一個非預期的字元,導致第一個識別符可能被破壞。像是 grep、awk 與 shell 管線這類 Unix 工具鏈,經常會將這三個位元組原封不動傳遞給並未預期它們的腳本。會檢查或驗證第一個位元組的 JSON、YAML 與 CSV 消費者,則會丟出剖析錯誤,或在第一個欄位塞入一個多餘的字元。即使是帶著 UTF-8 BOM 編譯的 Python 3 原始碼可以運作,但 Python 2 過去曾拒絕它,而許多第三方解析器至今仍如此。UTF-8 Converter 直接針對這個問題進行處理:被辨識出的來源 BOM 會由符合標準的解碼器吸收掉,而下載結果則由 UTF-8 編碼器產生,不會再加上 BOM。

為什麼這個工具拒絕猜測編碼

將檔案轉換為不含 BOM 的 UTF-8 時,最重要的單一原則是:來源編碼必須被明確選取。同一段位元組序列在多種舊式編碼下都可能合法,卻代表不同的字元,所以自動猜測即便看起來合理,仍可能損毀姓名、標點或符號。UTF-8 Converter 因此不偵測編碼:它要求你選出當初實際寫入該檔案的編碼,使轉換過程保持可稽核。若選到錯誤的編碼,預覽通常會在你按下下載之前就先顯示出亂碼,這時你可以切換來源選項並重新轉換,而無需重新上傳檔案。

這項轉換是在本機進行的。瀏覽器透過 File API 讀取檔案,以你選定的 WHATWG 編碼標籤解碼,再以瀏覽器的 UTF-8 編碼器重新編碼結果,最後透過一個可撤銷的 Blob URL 將位元組暴露出來。原始檔案會保留在磁碟上,除非你主動選擇覆寫,否則不會被動到。

將檔案轉換為不含 BOM 的 UTF-8

  1. 判斷並選定檔案真正的來源編碼,而非憑外觀猜測。請檢查產生該檔案的應用程式、檔案所記錄的來源,或任何記載當初寫入位元組所用編碼的可信中繼資料。
  2. 選擇一個大小不超過 10 MB 的文字檔,進行轉換,並在預覽中檢查非 ASCII 字元。預覽會以選定的來源編碼來解碼這些位元組,因此任何明顯錯誤的選擇都會在此顯現。
  3. 下載 UTF-8 檔案,在目標應用程式中測試,並保留原始檔案直到驗證完成。下載的檔案是由 UTF-8 編碼器產生且不含 BOM,因此會從解碼後文字的第一個字元開始。

此工具支援的來源編碼

四種支援的來源編碼涵蓋了多數讀者在實務上會遇到的格式。每種編碼都有不同的位元組配置,選錯編碼會產生一個能順利解碼、卻與原始檔案呈現不同字型的檔案。

來源編碼適用時機此工具對應的 BOM 行為
UTF-8該檔案是以 UTF-8 儲存,可能帶有開頭 BOM。驗證過程為嚴格模式:無效的後續位元組、截斷的序列,以及被禁止的編碼,會導致明確的失敗,而非以替代字元取代。開頭的 UTF-8 BOM(EF BB BF)會被解碼器吸收。輸出不會再附加 BOM。
UTF-16LE低位元組在前,常見於 Windows 工具,以及由特定執行階段所儲存的許多 Unix 文字檔。相符的 FF FE BOM 會在解碼時被辨識並移除;輸出不含 BOM。
UTF-16BE高位元組在前,常見於較舊的 Java 成品、網路協定,以及大端序的傾印檔。相符的 FE FF BOM 會在解碼時被辨識並移除;輸出不含 BOM。
Windows-1252西歐的舊式字碼頁,常被誤標為 ISO-8859-1。80 到 9F 這段位元組包含可列印的標點與符號,例如歐元符號與花式引號。沒有來源 BOM。輸出代表的是將解碼後的字元重新編碼為 UTF-8,而非逐位元組複製。

每一種編碼如何處理來源 BOM

UTF-8 BOM 的處理是重點案例:開頭的 EF BB BF 會被視為一個標記,由符合標準的解碼器吸收並丟棄,使下載的檔案從第一個真正的字元開始。UTF-16LE 與 UTF-16BE 模式則在位元組順序上有所差異。即使成對的位元組仍可讀,一旦位元組順序顛倒,檔案中的字母就可能變成無意義的內容。對於先存放低位元組的格式,請選小端序;對於先存放高位元組的格式,則請選大端序。相符的 BOM 會被辨識並移除。像是表情符號這類輔助字元會使用 UTF-16 代理對,而此工具會在產出 UTF-8 輸出之前,將一組有效的高位與低位代理合併成單一 Unicode 純量值。不成對或格式錯誤的序列會在嚴格解碼下被拒絕,避免在聲稱轉換成功時悄悄輸出取代用的方塊。

預覽能抓到什麼、不能抓到什麼

預覽是一項快速的視覺檢查,用以確認解碼後的字元是否正確。請閱讀具代表性的行:帶有腔調字的姓名、花式引號或破折號這類標點、貨幣符號,以及任何非 ASCII 的行。錯誤的來源編碼通常會立刻以亂碼顯示出來。預覽不一定會顯示每一個控制字元或正規化上的差異,因此對於混合多種文字、需進行 Unicode 正規化,或含有隱形字元的檔案,請另行安排以十六進位檢視器進行後續檢查。

來源與輸出之間的位元組數不同是可預期的,並不單獨代表資料遺失。Windows-1252 將大多數字元打包為一個位元組,而 UTF-8 會將其中許多相同的字元展開為兩個或三個位元組。反向的情況則發生在 UTF-16 輸入:UTF-16 的代理對會摺疊成四個位元組的 UTF-8 序列。頁面會顯示來源與輸出的位元組數,使膨脹或縮減的狀況一目了然。

當單一檔案無法可靠解碼時

若來源檔案中混合了多種編碼,單一解碼器無法可靠地修復它。例子包括:一份 Windows-1252 的 CSV 中混入從網頁匯出貼上的 UTF-8 列;或一份 UTF-8 來源檔案中,有人直接以 Windows 編輯器貼上未經重新編碼的位元組而替換了某個段落。請沿著交界處將檔案切開,以正確的來源編碼分別轉換每一段,再將解碼後的文字串接起來,而非串接原始位元組。同樣的原則也適用於控制字元與換行符號的漂移:它們會以解碼後的字元形式保留,但轉換器不會對 Unicode 進行正規化,也不會修改換行符號,僅止於解碼與 UTF-8 編碼所必然產生的變動。

當 10 MB 的上限代表你需要不同的工具時

檔案大小上限為 10 MB,是因為瀏覽器的 File 與 Encoding 介面在此處是針對記憶體中的緩衝區運作。為了避免意外載入過大的檔案,會在讀取前先檢查大小。對於資料庫傾印檔、多 GB 的紀錄檔,或媒體清單,請使用具備明確來源與目的編碼、可信且支援串流的轉換工具,因為將整個檔案讀入記憶體並不實際。此處採用的標準記載於 WHATWG Encoding 規格 與 RFC 3629,兩者皆定義了位元組如何被解碼,以及輸出中一個合法 UTF-8 序列的樣貌。

相關閱讀:Convert to UTF-8 API 替代方案:在瀏覽器中執行。