如何在Python中读取可以保存为ansi或unicode的文件?
我必须编写一个脚本来支持读取可以保存为 Unicode 或 Ansi 的文件(使用 MS 的记事本)。
我的文件中没有任何编码格式的指示,如何支持这两种编码格式? (一种在不提前知道格式的情况下读取文件的通用方法)。
I have to write a script that support reading of a file which can be saved as either Unicode or Ansi (using MS's notepad).
I don't have any indication of the encoding format in the file, how can I support both encoding formats? (kind of a generic way of reading files with out knowing the format in advanced).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
MS 记事本为用户提供了 4 种编码选择,用笨拙且令人困惑的术语来表达:
“Unicode”是 UTF-16,以小尾数法编写。 “Unicode big endian”是UTF-16,写作big-endian。在这两种 UTF-16 情况下,这意味着将写入适当的 BOM。使用
utf-16
解码此类文件。“UTF-8”是UTF-8;记事本明确写入“UTF-8 BOM”。使用 utf-8-sig 来解码此类文件。
“ANSI”令人震惊。这是 MS 术语,意思是“此计算机上的默认旧编码是什么”。
以下是我所知道的 Windows 编码及其所使用的语言/脚本的列表:
如果文件是在正在读取的计算机上创建的,那么您可以通过
获取“ANSI”编码locale.getpreferredencoding()
。否则,如果您知道它来自哪里,则可以指定要使用的编码(如果它不是 UTF-16)。如果失败的话,猜猜。在 Windows 上使用
codecs.open()
读取文件时要小心。文档说:“”“注意即使未指定二进制模式,文件也始终以二进制模式打开。这样做是为了避免由于使用 8 位值编码而导致数据丢失。这意味着在读取和写入时不会自动转换 '\n'。""" 这意味着您的行将以
\r\n
结尾,并且您需要/想要将其删除 使用将它们放在一起:
所有 4 个编码选项保存的示例文本文件在记事本中如下所示:
这是一些演示代码:
这是使用命令
在 Windows“命令提示符”窗口中运行时的输出 。 \python27\python read_notepad.py "" t1-*.txt
需要注意的事项:
(1) “mbcs”是一种文件系统伪编码,与解码内容完全无关 > 文件的默认编码为
cp1252
,它类似于latin1
(aarrgghh!!);参见下面的(2)
chardet
> 非常擅长检测基于非拉丁文字的编码(中文/日文/韩文、西里尔文、希伯来文、希腊文),但不太擅长基于拉丁文的编码(西欧/中欧/东欧、土耳其语、越南语),并且不太擅长阿拉伯语根本不。MS Notepad gives the user a choice of 4 encodings, expressed in clumsy confusing terminology:
"Unicode" is UTF-16, written little-endian. "Unicode big endian" is UTF-16, written big-endian. In both UTF-16 cases, this means that the appropriate BOM will be written. Use
utf-16
to decode such a file."UTF-8" is UTF-8; Notepad explicitly writes a "UTF-8 BOM". Use
utf-8-sig
to decode such a file."ANSI" is a shocker. This is MS terminology for "whatever the default legacy encoding is on this computer".
Here is a list of Windows encodings that I know of and the languages/scripts that they are used for:
If the file has been created on the computer where it is being read, then you can obtain the "ANSI" encoding by
locale.getpreferredencoding()
. Otherwise if you know where it came from, you can specify what encoding to use if it's not UTF-16. Failing that, guess.Be careful using
codecs.open()
to read files on Windows. The docs say: """NoteFiles are always opened in binary mode, even if no binary mode was specified. This is done to avoid data loss due to encodings using 8-bit values. This means that no automatic conversion of '\n' is done on reading and writing.""" This means that your lines will end in
\r\n
and you will need/want to strip those off.Putting it all together:
Sample text file, saved with all 4 encoding choices, looks like this in Notepad:
Here is some demo code:
and here is the output when run in a Windows "Command Prompt" window using the command
\python27\python read_notepad.py "" t1-*.txt
Things to be aware of:
(1) "mbcs" is a file-system pseudo-encoding which has no relevance at all to decoding the contents of files. On a system where the default encoding is
cp1252
, it makes likelatin1
(aarrgghh!!); see below(2)
chardet
is very good at detecting encodings based on non-Latin scripts (Chinese/Japanese/Korean, Cyrillic, Hebrew, Greek) but not much good at Latin-based encodings (Western/Central/Eastern Europe, Turkish, Vietnamese) and doesn't grok Arabic at all.记事本保存带有字节顺序标记的 Unicode 文件。这意味着文件的第一个字节将是:
其他文本编辑器可能有也可能没有相同的行为,但如果您确定正在使用记事本,这将为您提供自动选择编码的良好启发。然而,所有这些序列在 ANSI 编码中也是有效的,因此这种启发式方法可能会出错。无法保证使用正确的编码。
Notepad saves Unicode files with a byte order mark. This means that the first bytes of the file will be:
Other text editors may or may not have the same behavior, but if you know for sure Notepad is being used, this will give you a decent heuristic for auto-selecting the encoding. All these sequences are valid in the ANSI encoding as well, however, so it is possible for this heuristic to make mistakes. It is not possible to guarantee that the correct encoding is used.