? ? ? ? 網上看到篇好文章充择,解決了我多年的困惑闹啦,國內太需要這種不僅“知其然”還要“知其所以然”的文章了遣蚀。于是我無恥的記錄下來边锁。力爭以后自己也能多寫出這種筆記姑食。
(轉載)
你是否也和我一樣曾經好奇過為什么回車叫做回車呢?回車回的是哪門子的車茅坛,哪來的車音半?你是否知道回車和換行的區(qū)別呢?
前傳
在展開這個話題之前先說一個身邊的故事贡蓖。下面一段代碼是同事寫來處理一個簡單的文件然后輸出到另一個文件的代碼曹鸠,大家覺得有什么問題么?
string content;
using (StreamReader sr = new StreamReader("a.txt"))
{
content = sr.ReadToEnd();
}
string[] rows = content.Split('\n');
string result = string.Empty;
using (StreamWriter sw = new StreamWriter("b.txt"))
{
foreach (var row in rows)
{
//處理row
sw.WriteLine(row);
}
}
最后發(fā)現b.txt在某一些編輯器中每一行中間都多了一個空行斥铺,但是代碼里明明是每一行寫一次的彻桃,怎么會出現空行呢?
問題就處在content.Split('\n');這句話晾蜘,因為在Windows下文件的行末包含兩個字符\r\n邻眷,而不是僅僅是\n。用Notepad++打開一個文件看一下一目了然了:
Notepad++ 查看換行
回車和換行前世今生
回到最開始的那個問題剔交,換行符尚可理解肆饶,但是回車符這名字好奇怪,而且換一個行為毛需要兩個特殊字符呢岖常?
記得前幾天看過一篇關于光速安振創(chuàng)投副總裁張矩(Google前員工)的采訪:
Google認為計算機科學完全是由人基于理性的設計抖拴,和物理、化學等基礎性學科不一樣腥椒,它背后的原理是人可以理解的,也唯有理解了原理之后候衍,才能學會創(chuàng)新笼蛛。例如你需要了解TCP/IP為什么會設計成這樣,而不是只知道它是什么蛉鹿。在Google看來滨砍,只要人的基礎足夠好,在他們的環(huán)境下就可以做好,而且環(huán)境變了惋戏,以前的經驗未必有用领追。Google最早的幾個員工里,也只有兩個來自計算機專業(yè)响逢。
計算機里的一些設計往往是由特定的原因或者歷史問題才存在的绒窑,那么這個奇怪的回車是為什么存在呢?
從打字機說起
人們在使用最開始的打字機的時候舔亭,當打到一行末尾需要換行的時候些膨,需要做兩個操作。第一個就是拉動carriage講紙回到行首钦铺,然后再拉動換行桿將紙張向下移動一行订雾。這個設計影響了之后電傳打印機的設計,而電傳打印機的設計間接的影響了最開始計算機系統(tǒng)中的一部分設計(因為最開始的計算機需要兼容電傳打印機)矛洞。
打印機的那個裝置叫做Carriage洼哎,于是回到行首的這個操作就叫做Carriage Return,翻譯成中文就變成了回車沼本,這里的車其實是打印機上的一個裝置噩峦。后來的打字機則將這兩個操作合并到了一個操作裝置上去了。
ASCII碼的設計
大家都知道\r和\n是包含在ASCII碼中的擅威,ASCII是由ISO和ASA(ASNI的前身)同時設計的壕探,在ISO的標準草稿中支持CR+LF或LF作為新行標識,而ASA的標準草稿則支持CR+LF郊丛。
CR+LF之所以同時使用是為了兼容當時的電傳打印機李请,和老式打印機一樣電傳打印機需要兩個指令來完成一次換行。所以后來的很多系統(tǒng)中都沿用了這個CR+LF的慣例厉熟,將它們作為新行的標識导盅。
混亂的現狀
雖然很多系統(tǒng)沿用了這個慣例,但是還是有很多其他的系統(tǒng)使用了不同的換行方式揍瑟。
Windows:CR + LF
Unix及類Unix系統(tǒng)(Linux, OS X):LF 老板本
MacOS:CR
大部分的文本相關的因特網協議(Http, FTP, IRC, SMTP)都強制使用ASCII碼 CR+LF做換行符白翻。
這就導致了一個問題,文件如果從一個系統(tǒng)直接拷貝到另一個系統(tǒng)就需要對其中的換行符進行轉換才能夠正確的使用绢片。