UTF8文件帶BOM引起的問題 - 台部落
文章推薦指數: 80 %
UTF-8 不需要BOM,儘管Unicode 標準允許在UTF-8 中使用BOM。
所以不含BOM 的UTF-8 纔是標準形式,在UTF-8 文件中放置BOM 主要是微軟的習慣(順便提 ...
請輸入正確的登錄賬號或密碼
註冊
忘記密碼
首頁
未分類
正文
UTF8文件帶BOM引起的問題
原創
化身西湖雲
2019-06-2312:53
起因是公司iOS端竟然加載除了HTML代碼,百思不得其解,查文獻,原來如此...
UTF-8不需要BOM,儘管Unicode標準允許在UTF-8中使用BOM。
所以不含BOM的UTF-8纔是標準形式,在UTF-8文件中放置BOM主要是微軟的習慣(順便提一下:把帶有BOM的小端序UTF-16稱作「Unicode」而又不詳細說明,這也是微軟的習慣)。
BOM(byteordermark)是爲UTF-16和UTF-32準備的,用於標記字節序(byteorder)。
微軟在UTF-8中使用BOM是因爲這樣可以把UTF-8和ASCII等編碼明確區分開,但這樣的文件在Windows之外的操作系統裏會帶來問題。
「UTF-8」和「帶BOM的UTF-8」的區別就是有沒有BOM。
即文件開頭有沒有U+FEFF。
UTF-8的網頁代碼不應使用BOM,否則常常會出錯。
這是一個小例子:爲什麼這個網頁代碼
這個就不解釋了,Wikipedia上很詳細。
http://en.wikipedia.org/wiki/Byte_order_mark。
在網頁上使用BOM是個錯誤。
BOM設計出來不是用來支持HTML和XML的。
要識別文本編碼,HTML有charset屬性,XML有encoding屬性,沒必要拉BOM撐場面。
雖然理論上BOM可以用來識別UTF-16編碼的HTML頁面,但實際工程上很少有人這麼幹。
畢竟UTF-16這種編碼連ASCII都雙字節,實在不適用於做網頁。
其實說BOM是個壞習慣也不盡然。
BOM也是Unicode標準的一部分,有它特定的適用範圍。
通常BOM是用來標示Unicode純文本字節流的,用來提供一種方便的方法讓文本處理程序識別讀入的.txt文件是哪個Unicode編碼(UTF-8,UTF-16BE,UTF-16LE)。
Windows相對對BOM處理比較好,是因爲Windows把Unicode識別代碼集成進了API裏,主要是CreateFile()。
打開文本文件時它會自動識別並剔除BOM。
Windows用這個有歷史原因,因爲它最初脫胎於多代碼頁的環境(ANSI環境)。
而引入Unicode時Windows的設計者又希望能在用戶不注意的情況下同時兼容Unicode和非Unicode(Multiplebyte)文本文件,就只能藉助這種小trick了。
相比之下,Linux這樣的系統在多locale的環境中浸染的時間比較短,再加上社區本身也有足夠的動力輕裝前進(吐槽:微軟對兼容性的要求確實是到了非常偏執的地步,任何一點破壞兼容性的做法都不允許,以至於很多時候是自己綁住自己的雙手),所以乾脆一步到位進入UTF-8。
當然中間其實有一段過渡期,比如從最初全UTF-8的GTK+2.0發佈到基本上所有GTK開發者都棄用多locale的GTK+1.2,我印象中至少經歷了三到四年。
BOM不受歡迎主要是在UNIX環境下,因爲很多UNIX程序不鳥BOM。
主要問題出在UNIX那個所有腳本語言通行的首行#!標示,這東西依賴於shell解析,而很多shell出於兼容的考慮不檢測BOM,所以加進BOM時shell會把它解釋爲某個普通字符輸入導致破壞#!標示,這就麻煩了。
其實很多現代腳本語言,比如Python,其解釋器本身都是能處理BOM的,但是shell卡在這裏,沒辦法,只能躺着也中槍。
說起來這也不能怪shell,因爲BOM本身違反了一個UNIX設計的常見原則,就是文檔中存在的數據必須可見。
BOM不能作爲可見字符被文本編輯器編輯,就這一條很多UNIX開發者就不滿意。
順便說一句,即使腳本語言能處理BOM,隨處使用BOM也不是推薦的辦法。
各個腳本語言對Unicode的處理都有自己的一套,Python的#-*-coding:utf-8-*-,Perl的useutf8,都比BOM簡單而且可靠。
另一個好消息是,即使是必須在Windows和UNIX之間切換的朋友也不會悲催。
幸虧在UNIX環境下我們還有VIM這種神器,即使遇到BOM擋道,我們也可以通過setnobomb;setfileencoding=utf8;w三條命令解決問題。
最後回頭想想,似乎也真就只有Windows堅持用BOM了。
P.S.:本問題是自己的第150個回答。
突然發現自己回答得很少很少⋯⋯P.S.2:突然想起需要解釋一下爲什麼說VIM去除bomb的操作需要在UNIX下完成。
因爲VIM在Windows環境下有一個奇怪的bug,總是把UTF-16文件識別成二進制文件,而UNIX(Linux或者Mac都可以)下VIM則無問題。
這個問題從VIM6.8一直跟着我到VIM7.3。
目前尚不清楚這是VIM的bug還是我自己那個.vimrc文件的bug。
如有高手解答不勝感激。
--------------------------------------------------------- 有bom格式在開頭會多出3個字節EFBBBF,主要用於識別編碼。
bom應該是windows特有的,在製作網頁時會產生各種意想不到的問題,例如多輸出了一個空行,影響PHP的session或者cookies功能(出現headeralreadysent錯誤),甚至可能引起頁面的亂碼(那3個字節影響了瀏覽器對頁面編碼的處理),因此總是推薦使用無bom編碼。
爲了處理這個問題我甚至寫了一個批量處理的PHP腳本。
---------------------------------------------------------邸強,軟件開發ing張旭東、MingyueZhou、sapjax贊同幾周前還在爲BOM的問題苦惱着。
。
。
正如@樑海所說,“不含BOM的UTF-8纔是標準形式”,的確是這樣,無BOM使用得更多些,所以個人還是推薦一般情況下用無BOM的形式吧,除非有問題的時候,再考慮換有BOM的。
Windows系統保存的都是有BOM的,所以你可以看到,用記事本保存一個UTF-8的txt,其實是有BOM的,這一點需要注意。
另外不同的文本編輯器對於有無BOM的稱呼也略有不同,比如EditPlus,有BOM的稱爲UTF-8+,無BOM的稱爲UTF-8,而在Notepad++中,有BOM的被稱爲標準UTF-8,而無BOM則被稱爲UTF-8無BOM。
---------------------------------------------------------武龍飛,c/c++程序員,喜歡天文學,數學和心理學。
WeijingHuang、BillChan、ickyR贊同以下文字出自我的博客內容,從另一面解說不一樣的bom。
---------------------------------------------------------字符編碼相信是每個程序員的噩夢,只要是有中文的地方,總是會遇到各種編碼的問題,並且這種問題還非常難纏,尤其在linux上,因爲上面很多軟件都是針對英語國家開發的,是不會考慮其他語種編碼問題。
在遇到編碼的無數大坑之後,我決定仔細研究下編碼問題,因爲這就像一道坎一直橫在你面前,每次到這裏你都會跌到,每次爬起來之後,你都若無其事,這樣的人被稱作戰士,真正的戰士。
可惜是個力量戰士,做爲新時代的智力戰士,當然不能在那跌到然後又在這繼續跌到。
文件的存儲方式:文件都有自己的存儲格式,比如最常見的txt,cpp,h,c,xml,png,rmvb各種格式,還有自定義格式。
這些文件不論是什麼格式,都是存儲在計算機硬盤裏的2進制格存儲,對應不同文件格式,有不同的軟件解析。
這篇文章不談文件是如何存儲的,只談文件是如何解析的。
文本文件解析:文本文件對應於人類可以閱讀的文本,如何從2進制轉換爲文本文件呢?起初由於計算機在美國發明,自然大家考慮的是英語如何表示,英語字母總共26個,加上特殊字符,128個字符,7位既一個byte即可表示出來。
這個就是大家所熟知的ascill編碼。
對應關係很簡單,一個字符對應一一個byte。
但很快發現,其他非英語國家的文字遠遠超過ascill碼,這時候大家當然想統一一下,不同國家出了自己不同的編碼方式,中國的gb2312就是自己做出來的編碼方式,這樣下去每個國家都有自己的編碼方式,來回轉換太麻煩了。
這時候出現了新的編碼方式,unicode編碼方式,想將編碼統一,所以規定了每個字符對應的unicode碼。
1、很多文件都是ascii編碼,如果用unicode太浪費。
2、沒有標誌位說明該幾個字節來解析爲一個符號。
這時候拯救世界的utf出現了,utf是unicode的一種實現,只不過更聰明瞭。
utf16是佔用兩字節,或者四字節,utf32是佔用四字節。
utf8是很聰明的一種表示方式。
1、對於單字節符號,字節第一位爲0,後面7位表示字節編碼。
2、對於n字節符號,第一字節的前n位都設爲1,第n+1位爲0,其餘位位編碼位置。
對於不同的編碼,在文本的最前方有不同的標誌,unicode通常有兩位來表示分別是fffe,或者feff,fffe表示big-endian編碼feff表示litte-endian編碼。
utf8是efbbbf來開頭的。
可以看出來utf-8是自解釋的,所以不用帶這個標誌文件,大多數程序是可以識別的。
但有些程序不能識別這個標誌,比如php就會直接把這個標誌當文本解析,不會忽略。
相信很多遇到php輸出文本解析亂碼或者解析錯誤的同學都遇到這樣的問題。
最後說說如何去掉或者加上bom,如果有vim那最好不過了,去掉命令:setencoding=utf-8setnobomb添加命令:setencoding=utf-8setbomb---------------------------------------------------------帶BOM的UTF-8就是赤裸裸的流氓!!!!!!!!! windows總是自做聰明的做一些別人無法理解的事情!!!UTF-8是不需要BOM頭的~~~!! 從剛開始學習代碼(實在不能稱我做的東西爲程序)到現在,不曉得被這個BOM頭搞了多少次,特別是對於我這種完全自學的人,知道找一個BUG需要多久多久不???? 帶不帶BOM頭區別就在於這個BOM頭,祥見排名靠前的大神答案。
windows特有的奇葩。
請使用UTF-8不帶BOM頭!! 它產生的BUG包含但不僅限於:鍩--感謝@飛揚提供,參考其答案HTML空白行div之間莫明的間隔亂碼!如果你用ssl那麼一定會有問題!!! 順便再鄙視一下SONY的記憶棒、IPHONE的接口~~ 這種吐槽的東西就讓它摺疊吧--------------------------------------------------------帶BOM的UTF-8非常操蛋,經常造成莫名其妙的問題。
---------------------------------------------------------我都是用的UTF-8withoutBOM,帶BOM的經常出現亂碼---------------------------------------------------------notepad++會自動添加爲帶Bom的utf8比較坑爹---------------------------------------------------------建議編程人員能使用Mac編程的儘量使用Mac,Window是及其操蛋的操作系統。
其次,如果我們要讀取三方的文件並以UTF-8格式解析的時候一定要注意去判斷這個文件是否有BOM,例如:sql文件的解析執行。
---------------------------------------------------------網頁編程中用不用bom我就不說什麼了,因爲軟件原因無法使用的就更不能用了。
最近在學習用cocos2d-x,純C++的編碼,如果代碼中有中文等的非ascii字符出現。
發現會出錯。
代碼是在mac下用xcode寫的,放到windows下用vs編譯。
最後把所有的源文件轉成了帶bom的格式後編譯通過了,鏈接失敗,這想這個就不是編碼的問題了。
通常情況下,一般都會認爲在寫C++代碼的時候不要用中文,但是很多時候我們程序員也有想自己看着舒服的時候,爲神馬就不能寫中文了? 於是在windows下寫了一個helloworld.cpp類型的文件,輸出內容用中文,然後存爲utf-8帶bom格式,再把它copy到mac下用g++編譯,發現成功通過並且可正常運行,用xcode打開源文件也正常顯示。
所以,這裏建議程序要在windows和mac還有linux上運行的話,源代碼最好保存成utf-8帶bom的格式,這樣比較通用一些。
而用utf-16無論大端還是小端,g++都不認的。
或者用utf-8不帶bom格式,然後代碼不要出現非ascii127以後的字符。
關於說utf-8不帶bom纔是標準的,我想應該是帶用個人情緒的說法吧。
真正的標準應該是bom是可選的,爲什麼可選?因爲有些時候不帶bom會出錯,就拿歷史較久遠的windows來講吧,很多國家的用戶都在用windows,其文件都是用其本地的ansi編碼來做的,比如大陸的GBK和GB2013,港臺的big5,這些編碼因爲針對當地所用的字符制定的,所以呢,其存儲文件較小,所以會大量使用,並且也大量存在着,微軟不可能不考慮全球幾十億的用戶的文件而盲目地修改解碼方式,並且微軟也是uncode制定者之一,所以,帶用bom的utf-8也是符合國際標準的。
或許是因爲程序編寫者的個人原因,也許是考慮到效率,很多的程序無法正確區分一個utf-8文件是否有bom,所以導致了各種亂碼的出現。
個人不想說哪個是標準,也不想用語言去攻擊哪個公司或團體。
微軟在堅持使用bom上沒有錯,因爲這是在爲用戶考慮的。
也許給我們這些寫程序的帶來了不便,但是,計算機最廣泛的用戶不是程序員。
---------------------------------------------------------摘自:http://www.zhihu.com/question/20167122 發表評論 登录 所有評論 還沒有人評論,想成為第一個評論的人麼?請在上方評論欄輸入並且點擊發布. 相關文章 用編譯配置與環境變量實現開發時切換配置文件 開發人員在開發代碼的時候,經常會使用到Debug、Release、Development、Production等幾個概念,雖然有些地方在功能上最終殊途同歸,但是還是有非常大的區別。
首先需要搞清楚,Debug、Release都屬於編譯配置, 波多爾斯基 2022-10-1114:32:17 Xmakev2.7.2發佈,更加智能化構建第三方庫 Xmake是一個基於Lua的輕量級跨平臺構建工具。
它非常的輕量,沒有任何依賴,因爲它內置了Lua運行時。
它使用xmake.lua維護項目構建,相比makefile/CMakeLists.txt,配置語法更加簡潔直觀,對新 waruqi 2022-10-1114:31:37 [51nod1393]0和1相等串前綴和 #include
如果你當前的能力,小於i號怪獸的能力,你必須付出mon GreyZeng 2022-10-1114:24:56 從源碼分析MGR的新主選舉算法 MGR的新主選舉算法,在節點版本一致的情況下,其實也挺簡單的。
首先比較權重,權重越高,選爲新主的優先級越高。
如果權重一致,則會進一步比較節點的server_uuid。
server_uuid越小,選爲新主的優先級越高。
所以,在節點 iVictor 2022-10-1114:24:26 詳解MyBatis事務管理,徹底顛覆你對事務的理解! 來源:https://my.oschina.net/zudajun/blog/666764 前言 說到數據庫事務,人們腦海裏自然不自然的就會浮現出事務的四大特性、四大隔離級別、七大傳播特性。
四大還好說,問題是七大傳播特性是哪兒來的?是Sp Java技術棧 2022-10-1114:22:06 這個外包公司太噁心了。
。
進去請三思! 從ZH離開時,準備寫點東西揭露下ZH對外包的一系列噁心措施,但是感覺蚍蜉撼樹,什麼也改變不了,自己倒黴就認了,最近流行向前看嗎。
但是今天又聽到有同事被離場,心中光有怒火,還是無可奈何。
思來想去,決定寫點東西,如果能給那些準備去ZH(合肥) Java技術棧 2022-10-1114:22:06 獲取/resources目錄資源文件的9種方法,還有誰不會?! 項目開發中,經常會有一些靜態資源,被放置在resources目錄下,隨項目打包在一起,代碼中要使用的時候,通過文件讀取的方式,加載並使用; 本文中彙總整理了九種方式獲取resources目錄下文件的方法。
其中公用的打印文件方法如下: /* Java技術棧 2022-10-1114:22:06 支持Java8/11/17/19的框架,Solonv1.10.5版本發佈 Java輕量級應用開發框架。
可用來快速開發Java應用項目。
主框架僅0.1MB。
Helloworld: @Controller publicclassApp{ publicstaticvoidmain(Stri 劉之西東 2022-10-1114:21:46 vscodemarkdownWYSIWYG所見即所得編輯和預覽 一直使用Typora編寫markdown,隨着vscode在工作中使用的越來越多,產生了一個想法:能不能在vscode中寫markdown,減少軟件的成本? 可是vscode官方自帶的的markdown體驗卻一般般,那麼有沒有更好的mark 趙青青 2022-10-1114:21:16 Linux使用lsof查看文件是否被佔用或者端口被佔用,bash一行ifwhile lsof(listopenfiles)是一個列出當前系統打開文件的工具。
在linux環境下,任何事物都以文件的形式存在,通過文件不僅僅可以訪問常規數據,還可以訪問網絡連接和硬件。
如TCP和UDP等,系統在後臺都爲該應用程序分配了一個文件 CharyGao 2022-10-1114:17:35 化 化身西湖雲 24小時熱門文章 k8s入門之常見問題&命令 鬱金香用C寫一個定時器來循環獲取陽光 一文讀懂MySQL索引 09你這導師太假了,不如換個學術大佬! 高代技巧小記 11導師讓你造航母怎麼辦? 10我可以不用發論文了? 12水論文如何吹一個好故事 這個外包公司太噁心了。
。
進去請三思! 本次秋招最差面試體驗給到華爲! 最新文章 使用IntersectionObserver進行曝光打點 /usr/lib64/libstdc++.so.6:version`GLIBCXX_3.4.15'notfound的解決辦法 教你開發一個webpackplugin 如何預覽vue文件 關於babe-loader^8.0.6的配置問題 最新評論文章 [2022]TopRatedCheckPoint156-315.80ExamQuestions QualifiedWritingServiceinAustraliacanallowstudentstoachievebettergrades Takeassignmenthelpertoresolvethepaperquerieseasily UpdatedCompTIADA0-001ExamQuestions(2022) 美國黑金效果和其它速效藥的不同之處 MicrosoftDP-500PDFQuestion[2022]-SecretToPassExamInFirstAttempt-[PremiumDumps]
延伸文章資訊
- 1UTF-8与UTF-8 BOM - bijian1013 - 博客园
在我们通常使用的windows系统中,我发现了一个有趣的现象。我新建一个空的文本文档,点击文件-另存为-编码选择UTF-8,然后保存。
- 2UTF8文件帶BOM引起的問題 - 台部落
UTF-8 不需要BOM,儘管Unicode 標準允許在UTF-8 中使用BOM。 所以不含BOM 的UTF-8 纔是標準形式,在UTF-8 文件中放置BOM 主要是微軟的習慣(順便提 ...
- 3位元組順序記號 - 维基百科
位元組順序記號(英語:byte-order mark,BOM)是位於碼點 U+FEFF 的統一碼字符的名称。當以UTF-16或UTF-32來將UCS/統一碼字符所組成的字串編碼時,這個字符被用來...
- 4utf 8與utf 8無BOM的區別 - w3c菜鳥教程
utf-8(8-bit unicode transformation format)是一種針對unicode的可變長度字元編碼,又稱萬國碼。 bom—byte order mark,位元組序標記.
- 5「帶BOM 的UTF-8」和「無BOM 的UTF-8」有什麼區別
UTF-8不需要BOM來表明位元組順序,但可以用BOM來表明編碼方式。字元"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF。所以如果接收者收到以EF BB...