趣谈、浅析CRLF和LF
作为程序员,在处理文件和输入输出的时候经常要跟CRLF和LF打交道。可能大家多少知道一些,但总是记不清楚,我也是这样的,因此写下这篇博文,作为记录。
首先,明确他们的意思:CR(回车),LF(换行)。是不是有点别扭,有点难记?下面的趣谈能帮助大家记忆:
CR和LF是缩写,其实他们的全称分别是:"Carriage-Return"和"Line-Feed"。追本溯源的说,CR(Carriage-Return)和LF(Line-Feed)这两个词来源于打字机的发明和使用。
如果大家看过故事背景比较老的电影或者电视剧,那么对这个家伙如何工作会有一定的印象:当你用一个打字机的时候,asdfghjkl;'右边的那个按钮(在计算机键盘上,就对应着Enter键)被按下的时候,打字机的纸张卷动一行,而纸张的水平位置并不变化。打字机上另外还有一个手柄,那个手柄是专用来回车的,向左搬动那个手柄的时候,装纸的结构被松开,在弹簧的作用下弹回最右边(相当于打印头回到最左边)。所以当我们要换行的时候,实际需要两步操作,回车+换行(或者反过来)。
因此,打字机的纸张卷动一行,就是换行(LF, Line-Feed),再看看这个单词,有没有觉得很形象?Line-Feed就是往打字的地方“喂”了一行。
而将打印头从最右边归为到最左边,就是回车(CR, Carriage-Return),其实单词的字面意思就是“倒(马)车”嘛,真的很形象!有人可能会问,为什么CR里的"C"是"Carriage(马车)"而不是"Car(汽车)"呢?
因为打字机发明的时候,汽车还没发明嘛!
言归正传,为什么我们会遇到各种关于CRLF的问题呢?
在文本处理中, CR, LF, CR/LF是不同操作系统上使用的换行符.
Dos和windows采用回车+换行CR/LF表示下一行,
而UNIX/Linux采用换行符LF表示下一行,
苹果机(MAC OS系统)也采用换行符LF表示下一行。(注:有些人认为Mac Style是CR,我查了一些资料,发现应该是这样的:老的Mac是CR,后来的OSX全部改成了LF)
CR用符号’\r’表示, LF使用’\n’符号表示。
一般操作系统上的运行库会自动决定文本文件的换行格式。 如一个程序在windows上运行就生成CRLF换行格式的文本文件,而在Linux上运行就生成LF格式换行的文本文件。
在一个平台上使用另一种换行符的文件文件可能会带来意想不到的问题, 特别是在编辑程序代码时. 有时候代码在编辑器中显示正常, 但在编辑时却会因为换行符问题而出错。
很多文本/代码编辑器带有换行符转换功能, 使用这个功能可以将文本文件中的换行符在不同格式单互换。
在不同平台间使用FTP软件传送文件时, 在ascii文本模式传输模式下, 一些FTP客户端程序会自动对换行格式进行转换. 经过这种传输的文件字节数可能会发生变化. 如果你不想ftp修改原文件, 可以使用bin模式(二进制模式)传输文本。
另外,在使用github时,我们可能会遇到这样的设置问题:
在学习git软件,安装git到configuring the lien ending conversion时,有三个选项。
a.Checkout Windows-style,commit Unix-style line endings.
b.Checkout as-is,commit Unix-style line endings.
c.Checkout as-is,commit as-is line endings.
这里面讲到了做两个操作(Checkout,Commit)的三种处理line endings的操作(Windows-style,Unix-style,As-is)。
为什么会出现这三种处理line endings(行尾结束符)呢?在Git的帮助页面给出了很好的解释。
Reference From:https://help.github.com/articles/dealing-with-line-endings
If you're using Git to collaborate with others on GitHub, ensure that Git isproperly configured to handle line endings.
Every time you press return on your keyboard you're actuallyinserting an invisible character called a line ending . Historically, differentoperating systems have handled line endings differently.
When you view changes in a file, Git handles line endings in its own way.Since you're collaborating on projects with Git and GitHub, Git mightproduce unexpected results if, for example, you're working on a Windows machine,and your collaborator has made a change in OS X.
意思很好理解,就不翻译了。重视由于历史的原因,各种不同的操作系统在处理行尾结束符采取了不同的处理方法。而Git和GitHub
三种处理方式的不同:
CRLF->Windows-style
LF->Unix Style, Mac Style(注:有些人认为Mac Style是CR,我查了一些资料,发现应该是这样的:老的Mac是CR,后来的OSX全部改成了LF)
CRLF表示句尾使用回车换行两个字符(即我们常在Windows编程时使用"\r\n"换行)
LF表示表示句尾,只使用换行.
CR表示只使用回车.
在Git中如何转换?
在Git通过下面的命令配置
$git config --global core.autocrlf true
# Configure Git on Windows to properly handle line endings
解释:core.autocrlf是git中负责处理line endings的变量,可以设置三个值--true,inout,false.
设置成三个值会有什么效果呢?
If core.autocrlf
is set to true, that means that any time you add a file to the git repo that git thinks is a text file, it will turn all CRLF line endings to just LF before it stores it in the commit.。
设置为true,添加文件到git仓库(即提交代码)时,git将其视为文本文件。他将把crlf变成lf。
If core.autocrlf
is set to false, no line-ending conversion is ever performed, so text files are checked in as-is. This usually works ok。
设置为false时,line-endings将不做转换操作。文本文件保持原来的样子。
设置为input时,添加文件git仓库(即提交代码)时,git把crlf编成lf。当有人Check代码(即从git仓库迁出代码)时,按照input的方式,即不做修改,完全照搬git仓库里的。因此在window操作系统下,尽量不要使用这个设置。
Yet another way to show how autocrlf
works
1) true: x -> LF -> CRLF
2) input: x -> LF -> LF
3) false: x -> x -> x
where x is either CRLF (windows-style) or LF (unix-style) and arrows stand for
file to commit -> repository -> checked out file
其实总结起来,如果设置autocrlf=false,那么文本文件在git仓库里存储和被人check时都不做任何改变,依然保持原来的line-ending。而设置为true或input,其共同点为文本文件在git仓库里line-ending修改为lf,不管原来是什么样的line-ending。不同点为autocrlf=true会在有人Check代码(即从git仓库迁出代码)时把代码line-endings转换为CRLF,而autocrlf=input不会对line-endings做任何改变。
因此,如果你编辑代码的系统为windows,就要设置autocrlf=true。如果你编辑代码的系统为Linux/Mac,就要设置autocrlf=input.
参考文献:
1、百度百科 "CRLF" http://baike.baidu.com/link?url=scpmj275A8qM1JE0lCgLq0CRNp0ruiXg0t2Szno0cTCAvYwkXOzLbIAJMFNFL_i7kHumKILySfU2sMN5tMp71K
2、百度知道 "什么是CR和LF" https://zhidao.baidu.com/question/918032703926589059.html
3、"CR,LF,CR\LF,回车,换行" http://www.cslog.cn/Content/cr-lf-crlf-new-line-enter/
4、"CRLF和LF" http://www.tuicool.com/articles/IJjQVb
5、Git换行符之autoCRLF配置的意义 http://www.cnblogs.com/yepei/p/5650290.html
6、自定义Git-配置git https://git-scm.com/book/zh/v1/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E9%85%8D%E7%BD%AE-Git