새 JSON 파일은 BOM 없는 UTF-8로 저장하고, 기존 파일에서 BOM이 확인될 때만 utf-8-sig로 읽는 것이 기본 판단입니다. 한글이 보이지 않는다는 이유만으로 두 설정을 같은 문제의 해결책처럼 바꾸면, 저장 형식과 읽기 호환성 문제를 놓치기 쉽습니다. 먼저 파일 시작 부분의 BOM 여부를 확인한 뒤 저장과 읽기에 서로 다른 선택을 적용하면 됩니다.
BOM 오류와 한글 깨짐은 먼저 나눠 보세요
JSON을 열었을 때 첫 글자 부근에서 오류가 난다면 파일 맨 앞에 UTF-8 BOM이 붙었는지 확인할 만합니다. Python의 JSON 디코더는 입력 시작의 BOM을 허용하지 않아 ValueError를 일으킬 수 있습니다. 반면 한글이 \u 형태로 보이는 현상은 JSON 직렬화 표기와 관련된 문제일 수 있어, BOM과 같은 원인으로 단정하면 안 됩니다.
운영에서 저는 다음 순서로 범위를 좁힙니다.
- 파일을 만든 프로그램이나 편집기에서 UTF-8 BOM 저장 옵션을 확인합니다.
- 파일을 바이너리로 열어 시작 바이트가
EF BB BF인지 확인합니다. - BOM이 있으면 읽기 단계에서만
utf-8-sig를 검토합니다. - 새로 저장하는 파일은 BOM 없는
utf-8을 우선합니다.
utf-8과 utf-8-sig의 역할은 다릅니다
UTF-8은 바이트 순서 문제를 해결하기 위해 BOM이 필요한 인코딩이 아닙니다. utf-8-sig는 이름처럼 UTF-8 BOM을 다루는 변형입니다. 디코딩할 때 파일 시작의 BOM을 건너뛰고, 인코딩할 때는 UTF-8 BOM 바이트 EF BB BF를 앞에 붙입니다.
따라서 두 인코딩은 이렇게 구분하면 실수가 줄어듭니다.
| 상황 | 선택 | 이유 |
|---|---|---|
| 새 JSON을 저장 | utf-8 |
불필요한 BOM을 만들지 않음 |
| BOM이 있는 기존 JSON을 읽음 | utf-8-sig |
시작 BOM을 건너뜀 |
| BOM이 없는 일반 UTF-8을 읽음 | utf-8 |
원래 인코딩을 그대로 해석함 |
utf-8-sig를 모든 파일의 기본값으로 쓰기보다는, 외부 도구가 만든 기존 파일과의 호환성이 확인될 때 제한적으로 사용하는 편이 파일 형식을 예측하기 쉽습니다.
Python에서 저장과 읽기를 나눠 작성하기
새 파일을 저장하는 코드는 encoding="utf-8"을 명시하면 의도가 분명합니다.
import json
data = {"message": "한글 JSON"}
with open("data.json", "w", encoding="utf-8") as file:
json.dump(data, file, ensure_ascii=False, indent=2)
기존 파일에 BOM이 있다는 것이 확인된 경우에는 읽기 단계에서만 utf-8-sig를 사용합니다.
import json
with open("legacy-data.json", "r", encoding="utf-8-sig") as file:
data = json.load(file)
여기서 ensure_ascii=False는 한글을 JSON 문자열에 그대로 표시하기 위한 직렬화 옵션입니다. 파일의 UTF-8 BOM을 제거하거나 추가하는 인코딩 선택과는 별개입니다. 기본값인 ensure_ascii=True는 비ASCII 문자를 이스케이프할 뿐, 파일 인코딩 문제를 해결하는 설정은 아닙니다.
새 파일을 만들 때의 판단 기준
새로운 자동화 작업에서 JSON 파일을 만든다면 utf-8 저장을 기본으로 정합니다. Python 공식 문서도 JSON 상호운용성에서 UTF-8을 권장하고, JSON 시작 부분의 BOM은 허용하지 않는다고 설명합니다. Python의 JSON serializer는 BOM을 추가하지 않습니다.
이미 전달받은 파일을 읽는 경우에는 파일의 실제 형식을 존중해야 합니다. 오류가 난다는 이유만으로 utf-8-sig를 붙이기보다, 파일의 시작 바이트와 생성 도구의 저장 옵션을 확인하세요. BOM이 없다면 일반 UTF-8로 읽고, BOM이 있다면 utf-8-sig로 읽는 식입니다.
이 판단으로도 문제가 남으면 다음 질문을 별도로 확인해야 합니다.
ensure_ascii=False와 파일 인코딩은 어떻게 구분하나요?- JSON 저장 후 Python에서 읽기까지 왕복 검증하려면 어떻게 하나요?
공식 문서
- Python
json공식 문서 — JSON의 BOM 처리, UTF 계열 입력,ensure_ascii동작을 확인할 수 있습니다. - Python
codecs공식 문서 —utf-8과utf-8-sig의 BOM 처리 차이를 설명합니다. - Python 입출력 튜토리얼 — JSON 파일과 텍스트 파일의 인코딩 지정 방법을 안내합니다.