2008-10-10 1 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) 

편집는 : 파일 청크 크기를 제어 할 수 BLOCKSIZE 매개 변수를 추가했다.

+3

read()는 항상 전체 파일을 읽습니다. 아마도 .read (BLOCKSIZE)를 원할 것입니다. 여기서 BLOCKSIZE는 한 번에 읽고 쓸 수있는 적절한 양입니다. – Brian

+1

사실입니다. 고마워요. 내 예를 수정합니다. – DzinX

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

+0

@Arafangion 왜 바이너리 모드가 더 좋을까요? 감사! –

+0

@ Honghe.Wu : Windows에서 텍스트 모드가 기본값이며, 이는 줄 끝이 운영 체제에 의해 맹 글링됨을 의미합니다. 디스크의 인코딩이 확실하지 않은 경우 원하지 않는 방식입니다. – Arafangion

12

감사 답장을 위해, 그것을 작동합니다!

그리고 소스 파일이 혼합 된 형식이기 때문에, 나는 소스 형식의 목록을 추가

순서 ( sourceFormats)에서 시도하고, UnicodeDecodeError에 나는 다음 형식을 시도 : Rudro에 의해

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 
# ... 

(EDIT를 Badhon : 예외가 발생하지 않고 chardet.universaldetector를 사용하는 대체 접근 방식을 사용할 때까지 원래의 여러 형식을 통합합니다.

+0

어려운 경우에는 feedparser.org의 chardet 모듈을 사용하여 인코딩을 감지 할 수 있지만 경우에 따라 과도 함이 발생합니다. – itsadok

+0

파이썬 3.5는'file' 함수를 인식하지 못합니다. 그게 어디서 온거야? – physicalattraction

+0

예,이 답변은 8 년 전에 게시되었으므로 오래된 Python 2 코드 조각입니다. –

0

소스 인코딩이 무엇인지 추측하려면 file * nix 명령을 사용할 수 있습니다.

예 :

$ file --mime jumper.xml 

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

질문에 대답하지 않습니다. –

0

이 UTF-8 인코딩의 하나에 임의의 텍스트 파일로 변환하는 Python3 함수이다. (불필요한 패키지를 사용하지 않고)

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') 

쉽게 루프를 사용하여 파일 목록을 변환 할 수 있습니다.