UTF8文件帶BOM引起的問題 - 台部落

文章推薦指數: 80 %
投票人數:10人

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,否則常常會出錯。

這是一個小例子:爲什麼這個網頁代碼

內的信息會被瀏覽器理解爲在內? 另附《TheUnicodeStandard,Version6.0》之3.10D95UTF-8encodingscheme的一段話:WhilethereisobviouslynoneedforabyteordersignaturewhenusingUTF-8,thereareoccasionswhenprocessesconvertUTF-16orUTF-32datacontainingabyteordermarkintoUTF-8.WhenrepresentedinUTF-8,thebyteordermarkturnsintothebytesequence.ItsusageatthebeginningofaUTF-8datastreamisneitherrequirednorrecommendedbytheUnicodeStandard,butitspresencedoesnotaffectconformancetotheUTF-8encodingscheme.Identificationofthebytesequenceatthebeginningofadatastreamcan,however,betakenasanear-certainindicationthatthedatastreamisusingtheUTF-8encodingscheme.http://www.unicode.org/versions/Unicode6.0.0/ch03.pdf ---------------------------------------------------------首先,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 #include #definemaxn1000050 #definemax(a,b)((a)>(b)?(a):(b)) usingnamespacestd; intl[m Bunnycxk 2022-10-1114:29:27 一文讀懂MySQL索引 1索引簡介 1.1什麼是MySQL的索引 官方定義:索引是幫助MySQL高效獲取數據的數據結構 從上面定義中我們可以分析出索引本質是一個數據結構,他的作用是幫助我們高效獲取數據,在正式介紹索引前,我們先來了解一下基本的數據結構 說故事的五公子 2022-10-1114:26:06 k8s入門之常見問題&命令 問題 一、Kubernetes權威指南中com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:Couldnotcreateconnection Ryan_zheng 2022-10-1114:25:46 驅動開發:內核通過PEB得到進程參數 PEB結構(ProcessEnvirormentBlockStructure)其中文名是進程環境塊信息,進程環境塊內部包含了進程運行的詳細參數信息,每一個進程在運行後都會存在一個特有的PEB結構,通過附加進程並遍歷這段結構即可得到非常 yshark 2022-10-1114:25:26 驅動開發:內核R3與R0內存映射拷貝 在上一篇博文《驅動開發:內核通過PEB得到進程參數》中我們通過使用KeStackAttachProcess附加進程的方式得到了該進程的PEB結構信息,本篇文章同樣需要使用進程附加功能,但這次我們將實現一個更加有趣的功能,在某些情況下應用層與 yshark 2022-10-1114:25:26 打怪獸問題 打怪獸問題 作者:Grey 原文地址: 博客園:打怪獸問題 CSDN:打怪獸問題 題目描述 題目鏈接:牛客-打怪獸 開始時你的能力是0,你的目標是從0號怪獸開始,通過所有的怪獸。

如果你當前的能力,小於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]


請為這篇文章評分?