1. ‘\uFEFF’의 정체
- BOM의 종류 중 하나이다. BOM은 문서 맨 앞에 눈에 보이지 않는 특정 바이트(byte)를 넣은 다음 이것을 해석해서 정확히 어떤 인코딩 방식이 사용되었는지 알아내는 방법으로, 자세히는 이 파일의 유니코드의 endian은 무엇인지 알 수 있도록 파일의 처음에 2~3byte의 문자열을 일컫는다.
- BOM의 종류
방식 |
BOM |
UTF-8 |
EF BB BF |
UTF-16 Big Endian |
FE FF |
UTF-16 Little Endian |
FF FE |
UTF-32 Big Endian |
00 00 FE FF |
UTF-32 Little Endian |
FF FE 00 00 |
2. 문제점
- Unicode 표준에는 UTF-8에 대해서는 BOM을 적지 않도록 권고하고 있고, 고정이라 생략하는 것이 보통인데, 일부 Window 프로그램에서 자동으로 넣는다. 이 때 Linux나 Unix 기반 환경에서 문제를 일으킨다.
3. 해결법
- ‘\uFFEF’가 있으면 지우거나 빈 문자열로 교체하는 플로우를 넣는다
// 지우기 1
byte[] readedBytes = null;
byte[] data = out.toByteArray();
if (( data[0] & 0xFF ) == 0xEF
&& ( data[1] & 0xFF ) == 0xBB
&& ( data[2] & 0xFF ) == 0xBF ) {
int len = data.length - 3;
readedBytes = new byte[len];
System.arraycopy(data, 3, readedBytes, 0, len);
} else {
readedBytes = data;
}
String result = new String( readedBytes, "utf-8");
// 지우기 2
if (strTmp.startsWith("\uFEFF")) {
strTmp = strTmp.substring(1);
}
// 교체
strTmp = strTmp.replace("\uFEFF", "");
- python의 경우, encoding 방식을
utf-8-sig
로 명시하면 확실하게 utf-8로 인코딩됨을 전달하기에 BOM을 읽지 않는다.
str.replace("\uFEFF", "")
# or
with open(file_name, "r", encoding = 'utf-8-sig')