python困惑:unix(LF)和windows(CR LF)

一、发现问题

由于业务场景的要求,需要生成一批文件,下图为样板文件的部分截图:

python困惑:unix(LF)和windows(CR LF)

我不太喜欢做重复的劳动,所以用python很快写了一段脚本自动生成该文件,生成文件截图如下:

python困惑:unix(LF)和windows(CR LF)

哈哈,怎么样?是不是很有成就感?或者是不是自认为上述两个截图中的内容很一样?我当时就是这样想的,不过头大的事情还在后面:

python困惑:unix(LF)和windows(CR LF)python困惑:unix(LF)和windows(CR LF)

用Compare工具比对样板文件和生成文件的内容一模一样,但是为啥样长度不同???长度相差了201-194=7。文件内容有7行,长度相差7会不会和7行有关?换句话说,会不会和回车换行符有关?再仔细看,发现两个文件的格式不同。

python困惑:unix(LF)和windows(CR LF)

python困惑:unix(LF)和windows(CR LF)

二、Unix(LF)和Windows(CR LF)区别

通过查找资料得知Unix(LF)和Windows(CR LF)区别如下:

操作系统 表示下一行方法
DOS/Windows

回车+换行CR/LF 

或:\r\n

UNIX/Linux

换行LF

或:\n

MAC OS

回车CR

或:\r











各符号代表的含义:

符号 十进制ASCII码数 十六进制数
CR用'\r'表示 13 0x0D
LF用'\n'表示 10 ox0A

所以Windows平台上换行在文本文件中是使用 0d 0a 两个字节表示, 而UNIX和苹果平台上换行则是使用0a或0d一个字节表示。这也解释了两个文件长度为什么相差7。通过NotePad++“显示所有字符”的操作也可以验证这种说法。

python困惑:unix(LF)和windows(CR LF)

一般操作系统上的运行库会自动决定文本文件的换行格式。 如一个程序在windows上运行就生成CR/LF换行格式的文本文件,而在Linux上运行就生成LF格式换行的文本文件。 

在一个平台上使用另一种换行符的文件可能会带来意想不到的问题, 特别是在编辑程序代码时,有时候代码在编辑器中显示正常, 但在编辑时却会因为换行符问题而出错。 

一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix下打开的话,在每行的结尾会多车一个^M字符。

Dos和windows采用回车+换行CR/LF表示下一行,即^M$($不是换行符的表示,换行符没有表示出来,$是文本结束EOF的表示)

由于dos风格的换行使用\r\n,把这样的文件上传到unix,有些版本的vi不能识别\r,所以vi显示时在行尾会出现^M出来,但是有些就能识别\r\n,正常显示回车换行。

很多文本/代码编辑器带有换行符转换功能, 使用这个功能可以将文本文件中的换行符在不同格式间互换。在不同平台间使用FTP软件传送文件时, 在ascii文本模式传输模式下, 一些FTP客户端程序会自动对换行格式进行转换。经过这种传输的文件字节数可能会发生变化。如果你不想ftp修改原文件, 可以使用bin模式(二进制模式)传输文本。 

三、使用python+win7自动生成Unix(LF)格式文件

在win7+python2.7环境下,程序中的'\n'会被操作系统自动转成'\r\n'(例如造成上述文件长度不一致的问题),所以需要使用二进制写入的方式才可保持'\n'本色。

def saveTxt(self, filecontext, filename):
    filetext = open(filename, "wb") # wb以二进制形式保存文件内容,避免\n被转成\r\n
    filetext.write(filecontext)
    filetext.close()

四、参考

  1. https://zhidao.baidu.com/question/555955168392015652.html
  2. https://www.cnblogs.com/lihong/archive/2011/02/19/1958349.html
  3. http://blog.csdn.net/sanqima/article/details/50467154
  4. https://www.cnblogs.com/Flyleaves/p/5718040.html