BOM이있는 UTF-8을 Python에서 BOM이없는 UTF-8로 변환
여기에 두 가지 질문이 있습니다. 일반적으로 BOM이있는 UTF-8 파일 세트가 있습니다. BOM이없는 UTF-8로 (이상적으로는) 변환하고 싶습니다. codecs.StreamRecoder(stream, encode, decode, Reader, Writer, errors)
이것을 처리 할 것 같습니다 . 그러나 나는 사용에 대한 좋은 예를 실제로 보지 못합니다. 이것이이를 처리하는 가장 좋은 방법일까요?
source files:
Tue Jan 17$ file brh-m-157.json
brh-m-157.json: UTF-8 Unicode (with BOM) text
또한 명시 적으로 알지 못해도 다른 입력 인코딩을 처리 할 수 있다면 이상적 일 것입니다 (ASCII 및 UTF-16 표시). 이 모든 것이 가능할 것 같습니다. 알려진 Python 인코딩을 취하고 BOM없이 UTF-8로 출력 할 수있는 솔루션이 있습니까?
아래에서 제안 된 sol'n 1 개 수정 (감사합니다!)
fp = open('brh-m-157.json','rw')
s = fp.read()
u = s.decode('utf-8-sig')
s = u.encode('utf-8')
print fp.encoding
fp.write(s)
이로 인해 다음과 같은 오류가 발생합니다.
IOError: [Errno 9] Bad file descriptor
속보
댓글에서 실수는 'r +'/ 'r + b'대신 'rw'모드로 파일을 여는 것이므로 결국 내 질문을 다시 편집하고 해결 된 부분을 제거해야합니다.
"utf-8-sig"코덱을 사용하면됩니다 .
fp = open("file.txt")
s = fp.read()
u = s.decode("utf-8-sig")
unicode
BOM이없는 문자열을 제공합니다 . 그런 다음 사용할 수 있습니다.
s = u.encode("utf-8")
일반적인 UTF-8 인코딩 문자열을 s
. 파일이 크면 모든 파일을 메모리로 읽는 것을 피해야합니다. BOM은 파일 시작 부분에 단순히 3 바이트이므로 다음 코드를 사용하여 파일에서 제거 할 수 있습니다.
import os, sys, codecs
BUFSIZE = 4096
BOMLEN = len(codecs.BOM_UTF8)
path = sys.argv[1]
with open(path, "r+b") as fp:
chunk = fp.read(BUFSIZE)
if chunk.startswith(codecs.BOM_UTF8):
i = 0
chunk = chunk[BOMLEN:]
while chunk:
fp.seek(i)
fp.write(chunk)
i += len(chunk)
fp.seek(BOMLEN, os.SEEK_CUR)
chunk = fp.read(BUFSIZE)
fp.seek(-BOMLEN, os.SEEK_CUR)
fp.truncate()
파일을 열고 청크를 읽고 읽은 위치보다 3 바이트 일찍 파일에 씁니다. 파일이 제자리에 다시 작성됩니다. 더 쉬운 해결책은 newtover 's answer 과 같은 새 파일에 짧은 파일을 쓰는 것 입니다. 더 간단하지만 짧은 기간 동안 두 배의 디스크 공간을 사용합니다.
인코딩을 추측하려면 가장 구체적인 것부터 가장 적은 것까지 인코딩을 반복 할 수 있습니다.
def decode(s):
for encoding in "utf-8-sig", "utf-16":
try:
return s.decode(encoding)
except UnicodeDecodeError:
continue
return s.decode("latin-1") # will always work
UTF-16으로 인코딩 된 파일은 UTF-8로 디코딩되지 않으므로 먼저 UTF-8로 시도합니다. 실패하면 UTF-16으로 시도합니다. 마지막으로 Latin-1을 사용합니다. 모든 256 바이트가 Latin-1에서 유효한 값이기 때문에 항상 작동합니다. None
이 경우에는 대신 반환 할 수 있습니다. 실제로 폴백이므로 코드에서이를 더 신중하게 처리 할 수 있습니다 (가능한 경우).
Python 3에서는 매우 쉽습니다. 파일을 읽고 utf-8
인코딩으로 다시 작성합니다 .
s = open(bom_file, mode='r', encoding='utf-8-sig').read()
open(bom_file, mode='w', encoding='utf-8').write(s)
import codecs
import shutil
import sys
s = sys.stdin.read(3)
if s != codecs.BOM_UTF8:
sys.stdout.write(s)
shutil.copyfileobj(sys.stdin, sys.stdout)
이것은 BOM없이 모든 종류의 인코딩을 UTF-8로 변환하고 창 enlines를 범용 형식으로 대체하는 구현입니다.
def utf8_converter(file_path, universal_endline=True):
'''
Convert any type of file to UTF-8 without BOM
and using universal endline by default.
Parameters
----------
file_path : string, file path.
universal_endline : boolean (True),
by default convert endlines to universal format.
'''
# Fix file path
file_path = os.path.realpath(os.path.expanduser(file_path))
# Read from file
file_open = open(file_path)
raw = file_open.read()
file_open.close()
# Decode
raw = raw.decode(chardet.detect(raw)['encoding'])
# Remove windows end line
if universal_endline:
raw = raw.replace('\r\n', '\n')
# Encode to UTF-8
raw = raw.encode('utf8')
# Remove BOM
if raw.startswith(codecs.BOM_UTF8):
raw = raw.replace(codecs.BOM_UTF8, '', 1)
# Write to file
file_open = open(file_path, 'w')
file_open.write(raw)
file_open.close()
return 0
코덱을 사용할 수 있습니다.
import codecs
with open("test.txt",'r') as filehandle:
content = filehandle.read()
if content[:3] == codecs.BOM_UTF8:
content = content[3:]
print content.decode("utf-8")
configparser.ConfigParser().read(fp)
UTF8 BOM 헤더로 파일을 열 때 문제가 발생했기 때문에이 질문을 찾았습니다 .
ConfigPhaser가 오류를보고하는 대신 구성 파일을 열 수 있도록 헤더를 제거하는 솔루션을 찾는 사람들을 File contains no section headers
위해 다음과 같이 파일을여십시오.
configparser.ConfigParser().read(config_file_path, encoding="utf-8-sig")
이렇게하면 파일의 BOM 헤더를 불필요하게 제거하여 많은 노력을 절약 할 수 있습니다.
(나는 이것이 무관하게 들린다는 것을 알고 있지만 이것이 나처럼 어려움을 겪는 사람들을 도울 수 있기를 바랍니다.)
참고URL : https://stackoverflow.com/questions/8898294/convert-utf-8-with-bom-to-utf-8-with-no-bom-in-python
'Programing' 카테고리의 다른 글
Xcode의 여러 줄 주석 (0) | 2020.11.17 |
---|---|
확인하는 방법 (0) | 2020.11.17 |
vim에서 열린 파일의 디렉토리에 새 파일을 만드시겠습니까? (0) | 2020.11.17 |
Java에서 org.json.JSONObject를 사용하여 값을 어떻게 null로 설정합니까? (0) | 2020.11.17 |
Nodejs로 Excel 파일을 만드는 방법은 무엇입니까? (0) | 2020.11.17 |