如何在Python中将文件转换为utf-8?

Séb*_*rra 54 python encoding file utf-8

我需要在Python中将一堆文件转换为utf-8,而我在"转换文件"部分时遇到了麻烦.

我想做相当于:

iconv -t utf-8 $file > converted/$file # this is shell code
Run Code Online (Sandbox Code Playgroud)

谢谢!

Dzi*_*inX 47

您可以使用编解码器模块,如下所示:

import codecs
BLOCKSIZE = 1048576 # or some other, desired size in bytes
with codecs.open(sourceFileName, "r", "your-source-encoding") as sourceFile:
    with codecs.open(targetFileName, "w", "utf-8") as targetFile:
        while True:
            contents = sourceFile.read(BLOCKSIZE)
            if not contents:
                break
            targetFile.write(contents)
Run Code Online (Sandbox Code Playgroud)

编辑:添加BLOCKSIZE参数来控制文件块大小.

  • read()将始终读取整个文件 - 您可能需要.read(BLOCKSIZE),其中BLOCKSIZE是一次适当的读/写量. (4认同)
  • 在 Python 3 中:考虑使用 `open` 而不是 `codecs.open` (请参阅[此处](/sf/ask/367552111/ Between-open-and-codecs-open-in-python )) (3认同)
  • 没错,谢谢。我将修改我的示例。 (2认同)

Sta*_*ale 28

这在一个小测试中对我有用:

sourceEncoding = "iso-8859-1"
targetEncoding = "utf-8"
source = open("source")
target = open("target", "w")

target.write(unicode(source.read(), sourceEncoding).encode(targetEncoding))
Run Code Online (Sandbox Code Playgroud)


Séb*_*rra 13

谢谢你的回复,它的确有效!

由于源文件是混合格式,我添加了一个源序列列表,在sequence(sourceFormats)中UnicodeDecodeError尝试,然后我尝试下一个格式:

from __future__ import with_statement

import os
import sys
import codecs
from chardet.universaldetector import UniversalDetector

targetFormat = 'utf-8'
outputDir = 'converted'
detector = UniversalDetector()

def get_encoding_type(current_file):
    detector.reset()
    for line in file(current_file):
        detector.feed(line)
        if detector.done: break
    detector.close()
    return detector.result['encoding']

def convertFileBestGuess(filename):
   sourceFormats = ['ascii', 'iso-8859-1']
   for format in sourceFormats:
     try:
        with codecs.open(fileName, 'rU', format) as sourceFile:
            writeConversion(sourceFile)
            print('Done.')
            return
      except UnicodeDecodeError:
        pass

def convertFileWithDetection(fileName):
    print("Converting '" + fileName + "'...")
    format=get_encoding_type(fileName)
    try:
        with codecs.open(fileName, 'rU', format) as sourceFile:
            writeConversion(sourceFile)
            print('Done.')
            return
    except UnicodeDecodeError:
        pass

    print("Error: failed to convert '" + fileName + "'.")


def writeConversion(file):
    with codecs.open(outputDir + '/' + fileName, 'w', targetFormat) as targetFile:
        for line in file:
            targetFile.write(line)

# Off topic: get the file list and call convertFile on each file
# ...
Run Code Online (Sandbox Code Playgroud)

(由Rudro Badhon编辑:这包含原始尝试多种格式,直到您没有获得异常以及使用chardet.universaldetector的替代方法)


Sol*_*sei 9

未知源编码类型的答案

基于@Sébastien RoccaSerra

蟒蛇3.6

import os    
from chardet import detect

# get file encoding type
def get_encoding_type(file):
    with open(file, 'rb') as f:
        rawdata = f.read()
    return detect(rawdata)['encoding']

from_codec = get_encoding_type(srcfile)

# add try: except block for reliability
try: 
    with open(srcfile, 'r', encoding=from_codec) as f, open(trgfile, 'w', encoding='utf-8') as e:
        text = f.read() # for small files, for big use chunks
        e.write(text)

    os.remove(srcfile) # remove old encoding file
    os.rename(trgfile, srcfile) # rename new encoding
except UnicodeDecodeError:
    print('Decode Error')
except UnicodeEncodeError:
    print('Encode Error')
Run Code Online (Sandbox Code Playgroud)


Ces*_*esc 8

您可以使用这一行(假设您想从utf16转换为utf8

    python -c "from pathlib import Path; path = Path('yourfile.txt') ; path.write_text(path.read_text(encoding='utf16'), encoding='utf8')"
Run Code Online (Sandbox Code Playgroud)

您的$fileyourfile.txt的路径在哪里。

为此,您需要python 3.4或更高版本(现在可能需要)。

下面是上面代码的更易读的版本

    python -c "from pathlib import Path; path = Path('yourfile.txt') ; path.write_text(path.read_text(encoding='utf16'), encoding='utf8')"
Run Code Online (Sandbox Code Playgroud)


Moj*_*adi 5

这是一个Python3函数,用于将任何文本文件转换为 UTF-8 编码的文件。(不使用不必要的包)

def correctSubtitleEncoding(filename, newFilename, encoding_from, encoding_to='UTF-8'):
    with open(filename, 'r', encoding=encoding_from) as fr:
        with open(newFilename, 'w', encoding=encoding_to) as fw:
            for line in fr:
                fw.write(line[:-1]+'\r\n')
Run Code Online (Sandbox Code Playgroud)

您可以在循环中轻松使用它来转换文件列表。