【问题标题】:How to convert encoding of text file (which contains text of language other than English) from "UTF-16 LE" to "UTF-8" in Python?如何在 Python 中将文本文件的编码(包含英语以外的语言文本)从“UTF-16 LE”转换为“UTF-8”?
【发布时间】:2019-10-15 02:31:21
【问题描述】:

我的文件夹中几乎没有包含印地语文本的文本文件。但是那些文本文件在UTF-16 LE 编码中。我想将编码更改为 UTF-8 而不更改其中的文本。我该怎么做?

我编写了两个 python 文件,但它们都没有正常工作。当我运行它们中的任何一个以及更改编码时,它们会清除文件内容。这些是我的 Python 文件中的代码:

文件 1:

import os
for root, dirs, files in os.walk("."):  
    for filename in files:
        #print(filename[-4:])
        if(filename[-3:] == "txt"):
            f= open(filename,"w+")
            x = f.read()
            print(x)
            f.close()
            f1= open(filename, "w+", encoding="utf-8")
            f1.write(x)
            f1.close()

文件 2:

import codecs
BLOCKSIZE = 1048576
with codecs.open("ee.txt", "r", "utf-16-le") as sourceFile:
    with codecs.open("ee.txt", "w", "utf-8") as targetFile:
        while True:
            contents = sourceFile.read(BLOCKSIZE)
            print(contents)
            if not contents:
                break
            targetFile.write(contents)

【问题讨论】:

    标签: python unicode utf-8 utf-16 file-encodings


    【解决方案1】:

    在读取内容时,您没有指定文件在 utf-16 LE 中 - 并且尝试同时读取和写入同一个文件会造成混淆,这是行不通的。

    此外,除非您在服务器中运行此代码,否则可能会通过向您发送一个非常大的文本文件来进行攻击尝试,否则您不必担心文件大小,只需一次读取所有文件内容。 (为了让您有一个想法,圣经是一本大书,大小约为 3 MB(使用 8 位编码) - 即使是小型 VPS 服务器也将有大约 200MB 的内存可供您的程序使用 -也就是说,您可以一次转换一本 30 多本圣经大小的书)。典型的台式计算机的内存量会是此数量的几倍。

    此外,相对较新的“pathlib”Python 库可以轻松遍历所有文本文件,其 Path.read_textPath.write_text 方法将打开文件,以正确的编码读取或写入内容,然后关闭它在一个表达式中。由于使用此方法时,在写入文件时读取已经完成,我们可以简单地通过两次调用来完成:

    import pathlib
    for filepath in pathlib.Path(".").glob("**/*.txt"):
       data = filepath.read_text(encoding="utf-16 LE")
       filepath.write_text(data, encoding="utf-8")
    

    如果您希望安全起见,在文件转换过程中发生灾难性计算机崩溃的可能性极小,您可以写入一个不同命名的文件,然后执行删除/重命名 - 所以代码是这样的:

    import pathlib
    for filepath in pathlib.Path(".").glob("**/*.txt"):
       data = filepath.read_text(encoding="utf-16 LE")
       tmp_name = filepath.name + ".tmp"
       filepath.with_name(tmp_name).write_text(data, encoding="utf-8")
       filepath.unlink()
       filepath.with_name(tmp_name).rename(filepath.name)
    

    【讨论】:

    • 编译时得到这个,LookupError: unknown encoding: utf-8 LE
    • 啊,你的文件不是UTF-16 - 上面的代码是最简单的sn-p。一个真正的应用程序会首先尝试检测编码(尝试几个并选择一个没有错误的编码是一种方法)。
    【解决方案2】:

    在向您解释错误之前有两个有用的提示:

    我认为你应该删除打印。它只会让你感到困惑,它取决于操作系统和环境它将打印什么编码。

    尝试使用非常短的文件(很少字符)并检查两个文件的输入和输出,无论是文本还是字节。

    现在解决办法:

    在第一个示例中:您应该以已读的方式打开第一个文件 (r)。

    在第二个例子中:你打开同一个文件,第一步是读取,但在你读取文件之前你打开它来写入,所以你截断了文件,你将没有字符可以读取。

    使用ee.txt.tmp文件写入,最后如果没有错误可以移动tmp文件去掉.tmp前缀。

    一般来说:从不读写同一个文件。

    【讨论】:

    • 在第一个文件中,我将文件更改为“r”并删除了打印语句。它没有更改编码,而是将文本替换为一些随机语言文本。
    • 你确定你的原文是UTF16-LE吗?
    • 是的,UTF16-LE 格式的原文
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    相关资源
    最近更新 更多