2008-10-10 4 views

ответ

44

Вы можете использовать codecs module, например:

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) 

EDIT: добавлен параметр BLOCKSIZE контролировать размер файла чанка.

+3

read() всегда будет читать весь файл - вы, вероятно, хотите .read (BLOCKSIZE), где BLOCKSIZE - это подходящая сумма для чтения/записи сразу. – Brian 2008-10-10 14:21:21

+1

Это правда, спасибо. Я изменю свой пример. – DzinX 2008-10-10 14:24:07

25

Это работает для меня в небольшой тест:

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

target.write(unicode(source.read(), sourceEncoding).encode(targetEncoding)) 
+0

Еще лучше было бы указать двоичный режим. – Arafangion 2011-04-12 00:10:09

+0

@Arafangion Почему бинарный режим был бы лучше? Благодаря! – 2014-02-20 14:39:02

12

Спасибо за ответы, это работает!

И так как исходные файлы в смешанных форматах, я добавил список исходных форматов быть судимым в последовательности (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 
# ... 

(Редактируйте Rudro Badhon: это включает оригинальную попытку нескольких форматов, пока вы не получите исключение, а также альтернативный подход, который использует chardet.universaldetector)

0

Чтобы угадать, что такое исходная кодировка, вы можете использовать команду nix file *.

Пример:

$ file --mime jumper.xml 

jumper.xml: application/xml; charset=utf-8 
0

Это 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') 

Вы можете легко использовать его в цикле для преобразования списка файлов.