Chinaunix首页 | 论坛 | 博客
  • 博客访问: 160598
  • 博文数量: 16
  • 博客积分: 2000
  • 博客等级: 大尉
  • 技术积分: 195
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-29 08:28
文章分类

全部博文(16)

文章存档

2015年(1)

2010年(15)

我的朋友

分类: WINDOWS

2010-01-31 18:27:54

   今天在使用python写程序的时候,碰到一个系统级的问题:在linux下写的很好的*.py程序,拿到windows下用记事本打开就会出现很多黑块。而在windows下用记事本写的程序拿到linux下用vi打开后,会在换行处多一个^M符号。
 
   究其原因吗,经过多次google后发现问题是这样的:linux用vi编辑器编辑文本的时候,换行用一个\n(换行符,ASCII码值为10),而windows记事本编辑文本的时候,换行却用\r\n(一个回车加一个换行),所以用vi编辑的换行到windows里面都不识别,整个程序文件被windows当成一行处理了。 在windows下编辑的文本拿到vi里面之后,vi就会在每行把\r识别成八进制字符^M 。不同的系统移植还真是个问题,就是一个小小的文本也有这样的问题,更别说二进制代码的程序了。
 
   其实这个问题以前也碰到过,只是当时懒得解决,不过现在不同往日了,咱会用python了,这种妨碍视觉的恶魔,怎能继续作恶,大蟒蛇附体,把它干掉,于是三下五除二,写下了一下程序:(删除linux下面每行最后的那个^M)
 

#!/usr/bin/python
# -*- coding:utf-8 -*-
import os


filefullname = raw_input('please input the filefullname:')
rf = open(filefullname, 'r')

(path, filename) = os.path.split(filefullname)
(name, suffix) = os.path.splitext(filename)
newfilename = name + '.over' + suffix
newfilefullname = os.path.join(path,newfilename)
wf = open(newfilefullname, 'w')

producer = rf.read()
for i in range(len(producer)):
    if producer[i] != '\r':
        wf.write(producer[i])
rf.close()
wf.close()


程序很简单,读取所有的内容,过滤掉\r后写入另一个文件。

运行很成功,终于把可恶^M全部去掉了……


我想,接下来就是windows下记事本黑块问题了,奇怪的问题出现了,仍然使用上面的程序,在windows下居然也能解决掉黑块问题,我太惊讶了,上面的程序明明是删除\r的,而在linux下面的程序是没有\r的,难到是底层问题,我想到了python的可移植性。

证明猜想:在windows系统下写一个文本win.txt,内容是

asdf
jkl


在linux下用vi打开这个文件显示是这样的

asdf^M
jkl^M


在linux下用上面的去掉^M

$:python del_M.py

$:please input the filefullname:win.py

输出文件为win.over.py,改名为linux.py

在linux下用vi打开linux.py就正常了

再回到windows下,用记事本打开linux.py 以确定出现黑块

这样的话,win.py和linux.py就是不一样的了,文件大小自然也不一样了,win.py没黑块,linux.py有黑块

但是……用python读取这两个文件的时候,发现这两个文件的读取居然相同

在windows下启动python

>>> f1 = open('win.py', 'r')

>>> f2 = open('linux.py', 'r')

>>> f1.read()

'asdf\njkl\n'

>>> f2.read()

'asdf\njkl\n'

红字是输出,看来python的文件读取确实是把真实的文件内容给掩盖掉了,我深深的体会到这种高层次的编程语言有点欺骗消费者的意思,简直就是个奸商啊……

再看下面,它又在掩埋真相:

在windows下使用一个错误的程序也能删除黑块的问题到底是怎么搞的呢?

看这个主要的代码片段:           

    if producer[i] != '\r':
        wf.write(producer[i])

由于linux.txt文件里面根本就没有\r,所以这个if语句是永真的,也就是说,把这个if语句去掉,可以实现相同的功能(我试过了,确实如此),也就是说,python读取一个以\n作为换行符的文件 再保存的时候,python自动给加上了\r

无语中……


 
经过一个晚上的思索加搜索,终于发现问题所在:
 
Windows中,python在写文本文件的时候,如果碰到\n,自动添加\r(如果本来就有\r就另当别论了)来符合Windows文本文件的规范。而在写二进制文件的时候,则不会有这样的处理。
 
写文本文件:f = open(name, 'w') //碰到\n,自动添加\r
写二进制文件:f = open(name, 'wb')
阅读(2550) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~