微軟為什麼用帶 BOM 的 UTF-8,造成和多數系統的不兼容?

Mac 和linux都是不帶bom的


哦,直接全換 utf-8 然後文件打不開你負責啊


@vczh too yang 啊。如果經常去csdn答題就知道:

現在經常會遇到這麼一種人,他們在某些領域一竅不通,但是他們不願意誠懇詢問,而是故意一本正經的胡說八道一通,比如「1+1=2是小學生都知道的,還需要那麼多數學家研究幾百年?」,目的就是故意引人反駁。

然後就會有大牛出來一句句的跟他仔細解釋,到底是個什麼概念。但是他非但不會感謝,反而會繼續胡攪蠻纏。最後的結果呢?大牛被氣的不輕,他倒是學會了不少知識(雖然可能只是半瓶水),還給旁觀者留下這個人很厲害,懂得真多,大牛都差點說不過他的印象。

哦,對了,這種人還喜歡不斷地編輯問題,把別人教會他的東西一點點編輯到最初的問題當中去。新來的人就會覺得「題主說的沒錯啊,很詳細啊」


del %systemroot%
otepad.exe

問題解決。

就這麼個破事兒說成微軟強制所有文件加BOM一樣。


回答這個問題的各位,真知道bom是什麼嗎?為什麼你們誅心之論會這麼熟練啊!

bom的全稱是位元組序標記,對於多位元組的編碼,例如ucs2,ucs4,utf16,utf32,它用於標明位元組序。

對,它的標準名稱就是「位元組序標記」,而不是「文件格式檢測標記」。所以,單純從定義上來說,utf8作為位元組流編碼,是不應該加bom的,位元組流本身並無位元組序的概念。

然而,微軟使用帶bom的utf8確實是必須的,linux使用不帶bom的utf8也是必須的,根本不存在任何一方刻意製造不兼容一說。

linux使用不帶bom的utf8,一方面當然是因為utf8不需要bom,更重要的,是unix的設計邏輯沒法兼容帶bom的文本:一切皆文件,一切文件皆是流。

一個流可以被任意的切斷,獨立解析,而不會改變含義。所以它不能有頭,也不能有結尾。由於頭根本不存在,所以bom不允許存在,否則你把一個流切成一萬份,就必須在一萬個片段的前面加bom,這種對流內容的修改違背了設計。osx派生自bsd,而bsd也同樣遵循unix設計思想,所以無論對於linux還是osx,bom必然不能存在,無論有沒有微軟,都只能用無bom的utf8作為標準。這是unix設計理念所決定的,而不是所謂刻意製造不兼容。

而微軟呢?情形也差不多,無論unix如何指定,它都只能設計成有bom的utf8,原因是微軟的系統預設都是用戶當前代碼頁,當前代碼頁不是utf8,這樣,utf8作為非當前代碼頁格式就無法識別。utf8

的bom是微軟自己的一個創新,微軟增加的一個識別碼。雖然用位元組序標記當識別碼是不優雅的,但對windows來說這麼做不會有任何副作用。依賴一個明確定義的文件頭標記對Windows來說完全可接受。這是為了兼容微軟的歷史版本系統,而並不是刻意製造與unix血統系統的不兼容。

結論:其實各個操作系統對待utf8的方式,都是與自己的過往設計,與自己的舊版本兼容,linux/osx是為了兼容unix的基礎設計,windows則是為了兼容所有歷史版本的windows。至於與其他操作系統兼容,並不是最重要的。他們做出這樣的選擇,從技術上都是必然的,不存在任何一方刻意製造不兼容一說。


UTF本來作為一種紙上談兵的規範,沒有具體實現。微軟是第一個支持並實現的,但是為了區分文件頭信息,增加了自己定義的BOM。

*INX們也覺得UTF是好東西,應該支持,但是作為對當時的邪惡軸心微軟的警惕,大家秉承的宗旨是,凡是微軟的,我們都要反對。UTF是開放的公約,可以支持,BOM是微軟定義的規範,那絕對不能支持。

這個做法其實也很正常,萬一你支持了BOM,而微軟申請了專利,那就完蛋了,隨時掏授權費,不然會被控告。看看oracle怎麼拿幾行代碼向google索賠96億美金就知道了。

後來微軟被google超越,被apple逆襲,又搞出nokia這檔子傻事以後,大家發現這個外表兇惡的中年大叔原來也有蠢萌的一面,才觀感大改。微軟也適時的通過開源,小娜這些方式出來賣萌,現在大家也就其樂融融,再也不提他壟斷市場的事了。

當年web爆紅,google興起的時候,矽谷有句名言,微軟越來越像IBM,而google越來越像微軟。現在大家都洗白上岸的時候,oracle下定決心,要與全世界為敵,喜滋滋的接過了邪惡軸心寶座。

====

題目怎麼改了。。。如何支持無BOM的很簡單,帶了BOM的文件直接把文件頭3個位元組去掉就可以了。主流的編輯器都加入了支持,一般文件另存為,或者設置項里找一下就有了。


微軟:明明是我先的…


問題很迫真,編輯很 naive,回答很黑啊……

微軟為什麼用帶 BOM 的 UTF-8,刻意製造和多數系統的不兼容?

我不知道這是真開源狂熱粉問的還是怎麼來的,但是據我所知連認為「所有軟體都應該是自由軟體」乃至於「自由軟體是道德問題」的 RMS 都不會因為技術細節不一樣就批評人乃至於開陰謀論。(emacs lldb 那個是許可證不同)

(按照知乎的習慣和我這幾個月的心情,我暫時不想提萬聖節文件和前幾個星期的某些專利黑……)

Linux 在 UTF-8 成為標準後, 迅速跟進,支持了標準的 UTF-8 .

Unix 世界正好懶得搞支持,然後找著了個——或者應該說是搞了個——和 ASCII 兼容性良好得一塌糊塗的……(嘿,晚來就是這點好)

為何 windows 在此之後, 默認編碼仍然是 ANSI ?

因為最早只有 legacy code pages,然後微軟開了兼容性大法。

(ANSI 這四個字倒的確挺坑的)

OS X 系統從原來的 CR 改邪歸正變成了 LF . ( 與各 *nix 保持一致 )

為何在 windows 中依然要堅持 CRLF ? ( 結合 build2016 看待 )

OS X 改是從 Mac OS 改過來的,兼容性順手多砸一個也沒事。

(OS X 還敢在 x.y.[z] 這種地方刪 API 呢。)

CRLF 是否有其獨有的優勢 ?

打字機用過嗎?哦不,不能再用歷史了,不然你們要說歷史全都是坑……

HTTP 用過嗎?SMTP?

所謂安裝第三方軟體,那是治標不治本的。

例如

dir &> out.txt

這種從命令行輸出的文本,其編碼兼容性仍然存在問題。

Raw IO Stream 應該沒有 BOM 這個問題,誰編輯的……

BOM 不是記事本專坑嗎……()

*nix 使用的是 slash / 而 windows 實用的是 backslash

歷史坑之「跟著 IBM 學習了 COMMAND /option」

可能是從 windows 7 開始 ( 請求證實 ) , windows 支持了 slash /

Win32 API 都支持,倒是 .NET 不支持我不大高興。

% backslash 本身作為各路編程語言 ( 和正則表達式 ) 的轉義字元, 當路徑分隔符實在是太辛苦了

我私下也很好奇微軟那群人怎麼忍受日常 \ 的。

* * *

最後回到 BOM 的問題。

前面說了,UTF-8 的最大優點之一就是 ASCII 兼容性帶來的懶人友好度,順手加個 BOM 真的是故意玩爆炸。(UTF-8 沒有 Byte Order 這件事……都知道的吧)

和 ISO-8859 系列作編碼判斷?不帶 BOM 直接猜 UTF-8 準確率很高的。(啥,Bush hid the facts?那是 UTF-16LE 坑啦……)(啥,你怕前幾段都是 ASCII 然後漏檢了?默認是 UTF-8 假陽性反正也一樣嘛)

微軟這種東西我倒也不指望改了,順手做了個坑就要兼容下去的……

當然,要說回來的話,UTF-8 RFC3629 也允許了 BOM 存在(沒有推薦),不接受文件 BOM 反而還是得算在 Unix-like 世界各個程序太懶的身上。不過 RFC 裡面也知道 BOM 對於傳輸各種流(欸,cat 拼接和 shebang 不就是假設全都是普通流了嗎)來說非常反人類,舉了一些不該用 BOM 的例子(第七頁)。


據我所知,微軟用的是 UTF-16

UTF-8 (with or w/o) BOM 是後來的標準,你說先來的刻意製造不兼容是不是有點欽點的意味?


VC6先於C++98出現:為什麼VC6那麼多地方不符合標準

IE5or6先於W3C出現:為什麼IE那麼多地方不符合標準

微軟採用BOM先於UTF-8:……

不就是大家不喜歡微軟,然後就搞了個標準嘛,跟我黨做法有什麼區別。


原題目部分:

1.1 LF 與 CRLF

OS X 系統從原來的 CR 改邪歸正變成了 LF . ( 與各 *nix 保持一致 )

為何在 windows 中依然要堅持 CRLF ? ( 結合 build2016 看待 )

CRLF 是否有其獨有的優勢 ?

編輯來編輯去的,甭管引不引戰,為答題者帶來了很大的困擾好么。知道的還好,不知道的圍觀群眾看到我這答案還以為我夾帶私貨另起爐灶,我可不想被罵成智障。

============================

說一下CRLF的那個。

CRLF全稱是Carriage-Return Line-Feed,就是回車換行。回車是將游標移到行首,而換行則是將游標切換到下一行,這個流程來源自以前的打字機,需要先回車再換行書寫下一行。

有趣的是維基上有這麼一段話:

Most textual Internetprotocols (including HTTP, SMTP, FTP, IRC, and many others) mandate the use of ASCII CR+LF ("
", 0x0D 0x0A) on the protocol level, but recommend that tolerant applications recognize lone LF ("
", 0x0A) as well. Despite the dictated standard, many applications erroneously use the C newline escape sequence "
" (LF) instead of the correct combination of carriage return escape and newline escape sequences "
" (CR+LF) (see section Newline in programming languages below). This accidental use of the wrong escape sequences leads to problems when trying to communicate with systems adhering to the stricter interpretation of the standards instead of the suggested tolerant interpretation. One such intolerant system is the qmailmail transfer agent that actively refuses to accept messages from systems that send bare LF instead of the required CR+LF.

啥意思呢,大致說一下:

大多數英特網文本協議(比如HTTP呀,SMTP呀,FTP、IRC什麼的)在協議層說要用ASCII的CR+LF(也就是「
」啦,十六進位是0x0D和0x0A),但是呢,建議還是兼容一下單LF(就是「
」,十六進位的就不寫了)。

雖然標準說要用CRLF啊,但是其他的很多程序錯誤地把C語言裡面的換行轉義符「
」(LF)當成換行回車序列「
」(CRLF)在用...所以呢,這個猝不及防的小錯誤在與嚴格遵守CRLF標準的其他系統的接洽中搞出了好多大新聞。比如某個系統就拒絕單獨的LF...

所以啊,宣傳上出現了偏差,後果還是很嚴重的。使用CRLF本就是標準,微軟遵循了標準但是為啥還要背鍋...

短劇1:

MS:要做這個但是沒標準怎麼辦呢?自己發明一個吧。

OS:我們擬定一個標準,不能跟微軟的一樣。

[出現不兼容]

OS:微軟霸權主義亡我之心不死,其心可誅!

MS:為什麼這樣呢,明明是我先......

短劇2:

[背景:標準已經被擬定出來]

MS:這下我乖乖實現標準就不會有軟禍論了吧。

[然而OS並沒有按照標準來,出現不兼容]

OS:微軟霸權主義亡我之心不死,其心可誅!

MS:為什麼,會變成這樣呢......


======更===新======

上邊那個說別人"誅心"的 @pansz , 顛倒是非為什麼那麼熟練。

微軟為什麼用帶 BOM 的 UTF-8,造成和多數系統的不兼容? - pansz 的回答

一個流可以被任意的切斷,獨立解析,而不會改變含義。所以它不能有頭,也不能有結尾。由於頭根本不存在,所以bom不允許存在,否則你把一個流切成一萬份,就必須在一萬個片段的前面加bom,這種對流內容的修改違背了設計。osx派生自bsd,而bsd也同樣遵循unix設計思想,所以無論對於linux還是osx,bom必然不能存在,無論有沒有微軟,都只能用無bom的utf8作為標準。這是unix設計理念所決定的,而不是所謂刻意製造不兼容。

The Unicode Standard 第2.6章明確指出了 Unicode 提供 BOM 來顯式指出LE, BE或其他的 Unicode Scheme等。

http://www.unicode.org/versions/Unicode5.0.0/ch02.pdf#G19273

嗯,看來是 Unicode 委員會"違背了設計"咯?

到底是誰

真知道bom是什麼嗎

呢?

對了,聖戰士這個詞可不是我在這裡用的。

BOM本來就是為了遷就 BEer 而創造的。

誰先來的,誰後到的,是誰在打端序的聖戰:

ON HOLY WARS AND A PLEA FOR PEACE

https://www.ietf.org/rfc/ien/ien137.txt

36年過去了,真是一點兒都沒有變。

======原===文======

所以從這個問題和一些評論中能看出為什麼不能和共產主義戰士或聖戰士講道理。

微軟在先,那麼後來的標準與微軟不同則說明人民的眼睛是雪亮的,是微軟刻意製造不兼容;

微軟在後,那麼說明微軟與人民為敵,刻意製造不兼容;

標準啥都沒規定,但是別人的實現和微軟不一樣,說明那是大勢所趨,是微軟刻意製造不兼容;

標準規定了,微軟也做到了,但是標準還允許另一種實現方式,那麼說明該標準是為了遷就微軟而存在的,是微軟刻意製造不兼容。

最先破壞標準的最喜歡誣陷別人破壞標準,

正如當____的最喜歡給自己立____。

沒必要扭扭捏捏扯這麼多,大家都知道這只是一個意識形態問題罷了,那些都是幌子和牌坊而已。

總之,殺死那群咖啡樂,對吧?


明明是開源界的友善度們覺得MS的標準不【嗶——】,所以刻意繞開MS已經實現的標準……W3C,OpenGL不都這樣么


微軟:明明是我先,什麼都是我先的,VC6也好,BOM也罷……為什麼你們無視先後這麼熟練啊!


好吧,一切都是微軟的錯,微軟是歷史的罪人,是人類的公敵,他讓歷史倒退了幾十年,還讓我早上便秘了很久。我這麼回答,你滿意了吧?!


搞得有操作系統規定了程序員們只能用一種編碼方式保存文本文件一樣。問題是並沒有這回事。所以問題不成立。BOM是Unicode標準的一部分,軟體的作者可以自由選擇加不加BOM,比如Windows上的C#程序員可以這麼寫

File.WriteAllText ("Foobar.txt", "...");

來寫沒有BOM的UTF-8文件。要加BOM的程序員需要加一個Encoding參數才可以。嗯,這一定不是微軟在推廣沒有BOM的UTF-8。

但是市面上並非只有Unicode這個標準,比如在中國有強制執行的gb2312和gb18030標準等等,如果一個文本處理器的作者不能控制輸入文本的編碼,那麼就應該有義務檢測源文件的編碼。BOM的好處是可以在寫這類編碼的時候節省很多時間。因為UTF-8是ASCII的超集,不讀完文件不能確定一個文件到底是不是UTF-8,在缺少BOM的時候檢測文件編碼需要讀完整個文件。有BOM之後檢測工作只需要讀文件開頭幾個位元組。

BOM存在與否並不會自動產生兼容問題,無論軟體是在哪個平台上跑的。比如IE、Firefox、Chrome之類的瀏覽器,無論網頁里BOM有沒有,是否和伺服器發送的http頭和HTML頭裡面寫的content type不符(沒錯web伺服器經常發這種自相矛盾的東西)都可以正常顯示。儘管HTML和XML等格式設計了內容編碼的位置,但是文件里的內容編碼不怎麼可靠,文本編輯器一般不會自動根據保存時選擇的格式去修改HTML/XML。IE並不開源,FF和Chrome怎麼做的編碼檢查人人都可以去看。用.Net讀UTF-8文件的話,File.ReadAllText默認會自動檢測是否有BOM,Windows上直接用IsTextUnicode這個API也可以檢測文件編碼是否是Unicode,是否有BOM,NotePad就是用這個API來檢測沒有BOM的UTF-8文件。

當然,加了BOM之後一些程序會出問題,但是那是這些程序沒處理好編碼檢測的問題,經常這些程序只做了對西歐字符集的兼容。對於僅僅是不認識BOM但是認識UTF-8的程序,用腳本去掉BOM就好了。去掉BOM容易,要決定是否需要加上BOM還真不容易,需要讀完整個文件才行。

標準里說是可選的內容,對於寫解碼器的人來說就是應該處理的。HTTP標準里Accept-Encoding是可選的,難道有伺服器收到包含Accept-Encoding的請求的時候就拋異常?


數數多少跨平台的代碼在處理文件路徑正反斜杠費周折,真希望微軟支持或者兼容unix的有些方式,unix的方式更簡單優雅。

微軟知道多少人在跨平台上編譯和開發上受折磨嗎?明明知道大家都離不開開源代碼


正好看到SF上有人問了下面這個問題,和題主的行為簡直如出一轍:

「目前一個項目需要將願資料庫(sqlserver)中的數據取出並做一定處理後存入目標資料庫(mysql),但是mssql和mysql無論是sql語句還是內置函數很多地方都不統一(比如mysql的自增是auto_increment,mssql的自增是identity(1,1)),數據傳輸和轉換非常的不方便。同樣是使用sql語句的關係型資料庫,為什麼要這麼不統一呢?這是微軟的鍋嗎?"


微軟的初心肯定是好的,當時Unicode沒普及,各國都擴展ASCII,沒有這個BOM很可能識別錯誤,而Linux世界呢,Unicode編碼很普及而且英文文檔居多不必考慮這個問題。


問題日誌真是笑死了

世界上沒有標準,微軟創造一個標準,你們不去用,自己搞出來一套,還罵微軟不兼容


我怎麼記得對於個人用戶,M$的系統才是多數?(#滑稽)


推薦閱讀:

關於 llvm/clang 在 Ubuntu 下的安裝?
semaphore和mutex的區別?
購置筆記本電腦,Ubuntu專用,求品牌型號推薦?
世界為什麼開發 Linux?

TAG:macOS | MicrosoftWindows | Linux | Unicode統一碼 |