在Python 2.7中运行Ubuntu这段代码:
f = open("testfile.txt", "w")
f.write("Line one".encode("utf-16"))
f.write(u"\r\n".encode("utf-16"))
f.write("Line two".encode("utf-16"))
在Gedit中读取时,在两行文本之间产生所需的换行符:
Line one
Line two
但是,在Windows 7中执行并在记事本中读取的相同代码会在“第一行”之后生成难以理解的字符,但记事本不会识别换行符。如何在Windows中为UTF-16编写正确的换行符以匹配我在Ubuntu中获得的输出?
我正在为只能读取Unicode UTF-16的仅Windows应用程序编写输出。我花了好几个小时尝试不同的提示,但似乎没有任何东西适用于记事本。值得一提的是,我可以在记事本中成功将文本文件转换为UTF-16,但我宁愿让脚本首先正确保存编码。
答案 0 :(得分:8)
问题是您是在文本模式下打开文件,但是尝试将其用作二进制文件。
此:
u"\r\n".encode("utf-16")
...编码为'\r\0\n\0'
。
然后这个:
f.write('\r\0\n\0')
...将Unix换行符转换为Windows换行符,提供'\r\0\r\n\0'
。
当然,这会破坏您的UTF-16编码。除了两个\r\n
字节将解码为有效但未分配的代码点U + 0A0D这一事实,这是一个奇数个字节,这意味着你有一个剩余的\0
。因此,代替L\0
成为下一个字符,它是\0L
,又称䰀
,依此类推。
最重要的是,您可能正在为每个编码字符串编写新的UTF-16 BOM。大多数Windows应用程序实际上都会透明地处理它并忽略它们,所以你实际上只是在浪费两个字节/行,但它实际上并不正确。
第一个问题的快速解决方法是以二进制模式打开文件:
f = open("testfile.txt", "wb")
这不能解决多BOM问题,但它修复了损坏的\n
问题。如果要修复BOM问题,可以使用有状态编码,也可以为第一次写入的所有写操作明确指定'utf-16-le'
(或'utf-16-be'
。
但 easy 修复两个问题,是使用io
模块(或者,对于较旧的Python 2.x,{{1}模块)为你做所有艰苦的工作:
codecs