如何将文本文件(包含英语以外语言的文本)的编码从;UTF-16 LE“;至;UTF-8“;用Python?

如何将文本文件(包含英语以外语言的文本)的编码从;UTF-16 LE“;至;UTF-8“;用Python?,python,unicode,utf-8,utf-16,file-encodings,Python,Unicode,Utf 8,Utf 16,File Encodings,我有几个文件夹中包含印地语文本的文本文件。但是这些文本文件是采用UTF-16le编码的。我想将编码更改为UTF-8,而不更改其中的文本。我该怎么做 我写了两个python文件,但没有一个能正常工作。当我运行它们中的任何一个,同时更改编码时,它们会清除文件内容。以下是我的Python文件中的代码: 文件1: import os for root, dirs, files in os.walk("."): for filename in files: #print(fil

我有几个文件夹中包含印地语文本的文本文件。但是这些文本文件是采用
UTF-16le
编码的。我想将编码更改为
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)

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

我想你应该去掉指纹。它只会让您感到困惑,这取决于操作系统和环境,它将打印什么编码

尝试使用一个非常短的文件(几个字符),并检查这两个文件的输入和输出是否为文本和字节

现在,解决方案是:

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

在第二个示例中:打开同一个文件,第一步是读取,但在读取文件之前先打开文件进行写入,因此截断文件,将没有字符可读取

使用
ee.txt.tmp
文件进行写入,最后,如果没有错误,可以移动
tmp
文件以删除
.tmp
前缀


一般来说:永远不要在同一个文件上读写。

在读取内容时,您没有指定文件是utf-16 LE格式的,并且存在着试图同时读写同一个文件的混淆,这是行不通的

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

此外,相对较新的“pathlib”Python库可以简化对所有文本文件及其
路径的迭代。read_text
Path.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)

在第一个文件中,我将文件更改为“r”,并删除了print语句。它没有更改编码,而是将文本替换为一些随机语言文本。您确定UTF16-LE中的原始文本吗?是的,UTF16-LE中的原始文本在编译时设置此选项,
LookupError:unknown encoding:utf-8 LE
啊,这是您的文件中没有utf-16的地方-上面的代码是最简单的代码片段。一个真正的应用程序首先会尝试检测编码(尝试几个并选择一个没有错误的编码是一种方法)。