Microsoft開發記事本的團隊,是不是使用了一個非常弱智的行為來保存UTF-8編碼的文件?
我在學習Git的過程中看了一篇教程,對此感到疑惑。截圖來自某Git教程的博客。
樓下不要亂扯,NT 開發的 1991 年哪來的 UTF-8?90 年代初但凡支持 Unicode 的軟體都是 16 位,也會很自然地引入 Endianness Mark。Unicode 1.0 的時候,官方的 8 位表示形式只有 UTF-1,一種兼容 ISO 2022 的變長編碼,你估計沒聽說過對吧。
後來為了用戶體驗、二進位兼容性(這條要求相當難但對用戶很重要,誰叫 PC 軟體是二進位分發呢)的要求保留了 BOM 作為區分 UTF-8 和遺留編碼的方法。
BOM現在是unicode標準,其實是那些不支持BOM的軟體比較弱智。就是不記得IE支持不……
麻煩先看看Unicode的官方文檔是怎麼說的:UTF-8, UTF-16, UTF-32 BOM。
Q: Is the UTF-8 encoding scheme the same irrespective of whether the underlying processor is little endian or big endian?
A: Yes. Since UTF-8 is interpreted as a sequence of bytes, there is no endian problem as there is for encoding forms that use 16-bit or 32-bit code units. Where a BOM is used with UTF-8, it is only used as an encoding signature to distinguish UTF-8 from other encodings — it has nothing to do with byte order. [AF]
中文意思大致是:UTF-8的BOM不是用來標註大小端序(因為從編程角度看UTF-8本來就好比是個BYTE[]型的數組,而不像UTF-16好比WORD[]、UTF-32好比DWORD[]那樣每個元素超過一個位元組,所以不存在大小端序的問題),而是用來將它與其他編碼區分開來。
所以UTF-8加BOM是符合標準的。
連官方的文檔看都不看就敢出來黑屁?
插科打諢,得得瑟瑟,東拉西扯,像個民科。
////////////////////////////////////////////////////////////////////////////////
題主御焱問完問題就跑,別人來回答也不見他有半點回復,難不成問完問題就斷網了?
windows整個兒都是支持bom的,而且bom是標準推薦。不帶bom是個歷史問題...unix那邊的。
事實上微軟在遵守Unicode規範。如果遵守規範也是弱智的話,要麼制定規範的人弱智,要麼說這話的人弱智。我傾向於後者。
PS:有問題就解決問題,bom只不過是程序員入門的一個很小的問題,說什麼弱智不弱智毫無意義。並不弱智,而是和Linux的做法一樣遵守Unicode標準推薦的做法。至於那些說Linux不鳥BOM不標準之類的,你發現了么,他們的回答里雖然都去Unicode網站截了圖,卻只找了一票QA,為啥不直接看標準文檔?
https://www.unicode.org/versions/Unicode10.0.0/UnicodeStandard-10.0.pdf
為了方便大家看,這裡把那段文字截圖+引用一把:
然後對比較重要的部分簡單說明一下:
位元組序標記(BOM)
UTF-16和UTF-32這兩個Unicode文本編碼形式在讀寫文件和網路傳輸等序列化場景中對位元組序敏感。儘管Unicode理應只包含一種規則,但沒這個能量去要求處理器硬得扭個位元組序。
Unicode標準里的U+FEFF表示無寬度佔位符,而U+FFFE則壓根不是字元,他倆都是不可見內容,且是雙位元組鏡像,所以在頭部添加一個標記FEFF,如果雙方位元組序一致,取到的都是FEFF,否則另一方取到的時FFFE,既能指明位元組序是否正確,同時又都是不可見字元不影響文字表現。
而這樣的BOM標記同時也是指出文件中有Unicode的標記,稱之為Unicode簽名。UTF-16是可以把FEFF添加到頭部表示的,為了保持一致性,UTF-8添加EFBBBF作為簽名。無論哪種簽名方式,因為都是沒用的符號,所以通常不會讓人把它與後續的文字體弄混。
如果一個數據流(或者文件)以FEFF這樣的BOM作為開始,說明他很有可能包含Unicode字元。推薦在傳輸Unicode數據時使用BOM,但是如果已經用了別的簽名方法,就不該用BOM當Unicode簽名。
換句話說,MS在記事本里嵌BOM,不屬於不規範或者設計爛;UTF-8雖然位元組序無關,但是加上個Unicode簽名也並不是不合規矩的事情。Linux下的那些個工具,有自己的簽名方法,就那個首行注釋
#-*- coding:utf-8 -*-
這個也是編碼簽名,來自於Emacs(Specify Coding - GNU Emacs Manual),其它工具一般要麼有自己的標註方式,要麼參照了Emacs的標註方式,所以在Linux下不用BOM也是按照標準的推薦方法來做的做法。
如果說MS有什麼事情做得不夠規範,那就是在記事本等軟體里,把UTF-16編碼方式寫成Unicode這個名字。因為按照Unicode標準,Unicode本身不是個編碼表現形式,存儲文件為Unicode編碼這個說法是說不通的;記事本里保存成Unicode其實是保存成UTF-16。
反倒是說,很多人,包括很多常年寫代碼的人,無論在Windows下還是Linux下,既不用BOM,也不做與系統標準一致的標準簽名(比如在Linux下做coding標註),其實是屬於自己做得不標準,就不要去怪任何一方設計太傻了吧……(當然實際上很多做開發的人為了照顧用戶體驗,就算不寫編碼集標記也會想辦法探測系統默認編碼或者指定默認編碼來嘗試解讀你的文件,比如Python3里默認用UTF-8解析沒有編碼標註的源碼,算是開發者的妥協)
linux不遵循標準的時候linux吹們就說現在只有windows這樣了,微軟弱智;微軟不遵循標準的時候linux吹們就噴微軟垃圾,可見其雙標。。。可事實上就算只有windows這樣也特么意味著只有小部分系統不支持而已。。。
那不是自作聰明,也不是亂碼,只是Unicode標準中規定的BOM而已。雖然事實上大家都不遵守這個標準,但是也不能說遵守了這個標準就是弱智的行為。Windows程序一般都能很好的處理這個BOM,主要是跨平台的時候才會發生衝突。但是,憑什麼要求Windows去迎合其他平台的習慣呢?
另外,Win下面編程就別用記事本了吧,用IDE多好,幹嘛辛苦自己。
BOM是Unicode標準的一部分,當然題主想評論他弱智我也管不著,反正事實就是linux不支持Unicode的標準(逃
但是不得不說,vim和clang++都支持。所以我現在壓根就不想去測試自己的代碼和g++的兼容性。最基本的一個程序由不同編碼的cpp文件混合鏈接都做不到。
當年我學PHP(這種模板引擎式語言)時就看到這種不明覺厲的話,於是解決了一些問題(PHP文件中的BOM頭輸出到了最終的HTML開頭,而使老IE進入怪異渲染模式),並從此對BOM諱莫如深,對不透明處理BOM的編輯器也諱莫如深。
如今用了Nodejs(以類似CGI的方式拼接字元串輸出),代碼文件中BOM可能造成的影響已經不存在了(是否最終輸出BOM是透明書寫的),相反,在靜態文件伺服器中,為了給文本文檔(.js .txt)單獨指定編碼,事實上只能使用BOM。
換言之,BOM是為使用者服務的,或者說服務開發者更好地服務使用者的。而BOM處理不當出問題的地方,都是從事編程開發工作的內部環節。
因此,根據理性,而非根據單純地規範,不支持BOM的應當被定性為功能不完善。我見過的有:
老IEPHPJekyllJSON
為此我還特意寫了一個 npm 模塊,功能簡單但自己平時編程幾乎處處都要用:https://github.com/LongTengDao/j-utf不是,Microsoft開發記事本的團隊使用了一種很完善的,通行於Windows世界的方法來保存UTF-8編碼的文件。Microsoft記事本在文件的開頭添加了一個標記,讓幾乎所有Windows程序都能正確識別出這是一個UTF-8編碼保存的,而不是ANSI編碼保存的文件。
但是,代碼文件通常來說有其他的方法來表明它的編碼,很多代碼文件並不需要通過這種方法來表明編碼,而且來自Linux世界的很多程序並不能正確處理這種標記,所以會導致問題。Microsoft開發的記事本,是用來記錄給人閱讀的文本的,不是用來記錄給電腦解析的代碼的。
我估計,很多噴記事本垃圾的人。可能年級和記事本差不多。很可能尷尬的打了個平手。
對於WIN上原機給你帶的這些個程序。特指WINDOWS附件里的種種。不用就不用把。不要多說什麼。
我相信MS是覺得把記事本弄的逆天,也賺不到錢,所以不去好好弄。並非他弄不好。
還有啊,不要拿國內的環境類比國外。當初這些個現在看起來垃圾的玩意,可都是免費給的。要感恩啊。記事本一直就是個讓你湊合能看的玩意兒。以前在WINDOWS上硬鋼文本編輯,最次也是用寫字板。
我覺得關於 BOM,最牛的是 javac 的處理:never fix !!!
JDK-4508058 UTF-8 encoding does not recognize initial BOM
The assumption we made to implement this RFE is that the change would not
break existing real world application, this assumption is obvious not true,see #6378911. We decided to back out the change we"ve made and closed thisRFE as "will not fix", for compatibility reason.
第一點 UTF-8 With BOM 是符合標準的。
第二點,對於微軟來說一個是兼容,另一個是本地化,這些都是微軟要考慮的。
實際上在 Windows 系統上,中文環境中記事本默認編碼就是 GBK(CP936),如果 UTF-8 使用沒有 BOM 的編碼,就意味著需要去分析文件中的內容來檢測編碼,否則就會和本地化編碼衝突,導致亂碼。記事本作為一個簡單的,歷史悠久的工具自然沒有高級編碼檢測的功能。直接使用 UTF-8 With BOM,可以檢測文件前三個位元組判斷文件編碼判斷是否是 UTF-8,前兩個位元組判斷是否是 UTF-16,剩下的就是本地編碼了。
通過分析文本內容來判斷編碼有 Mozilla 的 universalchardet, 這個工具實際上使用了統計學做編碼識別,即判斷某些編碼中的高頻字,進行統計加權,計算權重,選擇最有可能的編碼,這就意味著檢測不一定準確。這個庫被 Notepad++ uchardet 等一系列開源工具使用。
IE 也有編碼檢測的 COM 介面: IMultiLanguage 但準確率不高。
記事本的歷史源遠流長,切記不要被一些錯誤的文章忽悠了因果關係。
回答前先貼出處: 創建版本庫
為啥說微軟這個做法是弱智呢?
因為當年UTF-8標準確實是允許加BOM的,但是,你一加,問題就來了:
很多舊的軟體在處理文本內容的時候,它只按ASCII編碼走,現在換成UTF-8,不加BOM,純英文的編碼和UTF-8是一模一樣的,所以舊軟體不用改。古老的編譯器也能處理UTF-8格式的文本。
加了BOM,舊軟體處理不了純文本,即使全部用英文也不行。
成千上萬的舊軟體怎麼能敦促他們儘快升級呢?根本不可能的事。
軟體領域,很多時候,你必須要用一些舊版本的軟體,而且不可能升級。
所以,微軟遵守這個弱智規範是比較弱智的。
當然你說兼容性不重要,我用的所有軟體保證都能正確處理BOM頭,那也沒關係,因為遲早你會遇到不能處理BOM的軟體/第三方庫。如果是開源軟體你可以順手幫他們修改成支持BOM的。
記事本 這種 10年都不更新的應用也會有開發團隊嗎? 逃
請求圖片還有 mime type 來確定文件的真正格式,為什麼不能用bom區分文本文件的編碼?每次都要靠猜?
那些說微軟遵守 unicode 的人,你們這是無視歷史啊。明明是有了弱智的 utf8 BOM,才有的帶 BOM 的 utf8 是合法的這一條規則。
Utf8 是無需 BOM,故意增加一個 unicode 轉碼的三位元組,不是弱智還能是啥。而且,現在事實上的 utf8 也都沒有 BOM。補充一下 unicode 的歷史。
曾經,包括微軟在內的 unicode 成員們認為,只要兩個位元組就足夠表示所有的字元了。所以,它叫 unicode,大統一,別無分號。但是,CPU 是有大小端的,兩個位元組表示一個字,就需要 BOM 這種東西來區分。但很快 unicode 就被打臉了,兩個位元組的 ucs2 不夠!我們現在至少需要四個位元組的 ucs4。所以雄心勃勃想把 Ascii 直接換成不兼容的 unicode 的方案事實上行不通,因為 unicode 自己兩位元組和四位元組也不兼容啊。所以,還是得使用與 ascii 和 unicode 雙位元組四位元組都兼容的 utf8。而 utf8 從一開始設計時就沒有 bom 問題。Windows NT 內核作為一個 unicode (ucs2) 原生系統,支持 bom,進而支持 utf8 時也帶入了 bom。如果說兩位元組 unicode 和 640K 內存足夠一樣是短視的話,把兩位元組 unicode 需要的 BOM 帶入原本設計是就考慮到位元組序不需要 BOM 的 utf8 就真是弱智。
嗯。最後 unicode 只有 ucs-2 和 ucs-4 兩個字符集。utf-8、utf-16、utf-32 是另外的字符集。utf-16 不等於 ucs-2。
制定 utf-8 的人還是 c、plan9、golang 那一群程序員,不是官僚。我用python次次運行中文re都報錯
連我自定義字元串測試都報錯內容大概是非gbk不支持可是我不知道在編譯器輸入的字元是什麼編碼啊於是我廢了老大勁去找了一套
猜編碼的東西,猜了半天也沒猜對後來我直接把東西寫進記事本
然後保存時的ansi改成gbk就能用了直接讀記事本內容,全程無bug由此可見一般正常的open函數都會自動過濾掉前面的頭除非你是自己寫個流,還不寫過濾那就不能怪記事本了看了這段描述,我覺得題主應該用的是「世界上最好的語言」PHP
推薦閱讀:
※一個特殊的亂碼問題?
※計算機系統是如何顯示一個字元的?
※GB2312、GBK、GB18030 這幾種字符集的主要區別是什麼?
※為什麼有時候"元"(yuan)字會變成"刀"(dao)字?
※顏文字使用的都是哪些編碼?裡面都有哪些國家的文字?
TAG:微軟Microsoft | MicrosoftWindows | 字元編碼 | CC | UTF-8 |