IT_etc/유용한 전산 지식들..

[펌] UTF-8 저장 시 BOM로 인해 발생되는 문제 해결 방법

JJun ™ 2010. 4. 9. 16:07

-------------------------------------------------------------------------------------------------

출처: http://blog.naver.com/PostView.nhn?blogId=tyboss&logNo=70067039504&widgetTypeCall=true

-------------------------------------------------------------------------------------------------

 

BOM으로 인해서 원하는 값이 안나올 경우가 발생한다

 

UTF-8로 저장된 파일을 UltraEdit로 오픈한 후 수정할 경우

unix에서 vi로 열어보면 맨 앞줄에 이상한 문자가 하나 추가되는 경우가 있을 수 있다.

 

이것으로 인해 원하는 결과을 얻을 수 없을 경우가 발생한다.

 

 

1. UltraEdit에서 BOM제거 설정

UltraEdit의 경우 다음 옵션을 %SystemRoot%\UEdit32.INI에 넣어주면, BOM 없이 저장할 수 있다.
Write UTF-8 BOM = 0          #기존 파일을 UTF-8로 저장했을 때, BOM을 붙일 것인가를 지정

Write UTF-8 BOM NF = 0     #새 파일을 UTF-8을 사용하여 만들었을 때, BOM을 붙일 것인지 지정

(0이 붙이지 않음, 1이 붙임)

 

 

2. Editplus에서 BOM제거 설정
Tools > Preferences > Files > UTF-8 signature 항목에서

세번째인 Always remove signature 를 선택하면 된다.

혹은 "새이름으로 저장"해서 BOM이 없는 UTF-8 인코딩 방식을 바꾸면 된다.

 

 

 

 

3. Eclipse에서 BOM제거 설정
이클립스에서 작업 할 경우 원칙적으로 BOM을 제거한 후 작업이 되며 기존에 사용하던 소스에 BOM이

있을 경우 우선 파일을 MS949로 변환한 후 BOM제거 후 다시 UTF-8로 파일 속성을 변경하면 된다. 

 

-------------------------------------------------------------------------------------------------

 

다양한 언어를 표현할 수 있도록 해주는 유니코드(Unicode) 인코딩에는 여러가지 방식이 있습니다.

최근 웹 환경에서 많이 쓰이는 UTF-8을 비롯해서 UTF-16, UTF-32 등이 이런 인코딩 방식을 나타내지요.

이렇게 비슷한 방식을 사용하는 문서는 Byte Order Mark(BOM)로 구별이 됩니다.

문서 맨 앞에 눈에 보이지 않는 특정 바이트(byte)를 넣은 다음 이것을 해석해서 정확히 어떤 인코딩 방식이

사용되었는지 알아내는 방법이지요.

그런데 UTF-8 인코딩 방식에서는 BOM이 문제를 일으킬 수 있습니다. BOM이 무엇이고 왜 문제를

일으키는지, 그리고 어떻게 해결해야 하는지 알아보겠습니다.

BOM의 용도와 종류

BOM은 인코딩된 문서 첫 머리에 사용되어 정확한 인코딩 방식을 알려주는 역할을 하는데 대표적인 인코딩 방식과 그에 따른 BOM 목록은 아래 표와 같습니다.

 

인코딩 방식 Byte Order Mark(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개의 바이트가 FE FF로 시작되면 그 문서는 UTF-16 Big Endian으로 해석되고,

반대로 FF FE로 시작되면 UTF-16 Little Endian으로 해석되는 것이지요.

그런데 UTF-8은 다른 인코딩 방식과는 다르게 BOM의 순서가 EF BB BF로 정해져 있습니다.

그래서 이 BOM은 바이트 순서와(Byte Order) 상관없기 때문에 UTF-8 Signature라고 불리지요.

즉, 해당 문서가 UTF-8로 인코딩되었다는 사실을 알리는 사인(signature)입니다.

UTF-8 BOM으로 생기는 문제

UTF-8은 인코딩 형식이 고정되어 있기 때문에 BOM이 없어도 인코딩 방식을 자동으로 알아낼 수 있습니다. 따라서 실제로는 BOM이 불필요하지요.

하지만 일부 윈도우즈 프로그램(메모장 같은)은 UTF-8 파일을 생성할 때 자동으로 BOM을 집어넣습니다. 윈도우즈 환경에서는 눈에 띄지 않는 경우가 많지만 리눅스(LINUX)나 유닉스(UNIX) 환경에서는 많은 문제를 일으키는 원인이 되지요.

대표적인 예로 PHP에서 include 구문을 사용할 때 생기는 여백(space)을 들 수 있습니다.

이것은 비단 BOM의 문제 뿐 아니라 웹 서버의 설정과도 관련이 있기 때문에 모든 경우에 생기는 문제는

아닙니다. 먼저 인터넷 익스플로러(이하 IE)에서 아래 두 링크를 열어보시기 바랍니다.

BOM이 있는 문서 인클루드, BOM이 없는 문서 인클루드

두 문서는 이미지를 인클루드하는 부분을 제외하면 같은 소스를 사용합니다.

인클루드되는 파일 역시 BOM 유무를 빼면 동일합니다.

따라서 브라우저에서 두 문서의 소스를 확인해 보면 전혀 차이가 없습니다.

하지만 IE에서 두 페이지는 다르게 보입니다.

† 파이어폭스는 문서 내에 BOM이 들어가도 제대로 처리합니다. 따라서 두 링크가 동일하게 보이지요.

또한 웹 서버 환경에 따라서도 문제 발생 여부가 달라집니다.

동일한 파일을 다른 서버에 올릴 경우에는 문제가 안생길 수도 있으니까요.

UTF-8 BOM 문제의 원인

이렇게 두 문서가 다르게 보이는 이유는 눈에 보이지 않는 BOM 때문입니다. 사실 두 문서는 완전히 동일하지 않거든요. 단지 이 차이가 일반적인 환경에서는 보이지 않을 뿐입니다. 하지만 인클루드 되는 파일을 헥사 에디터((hex editor)로 열어보면 아래 이미지처럼 차이가 드러납니다.

 

test1.html에서 인클루드한 BOM이 있는 파일입니다.

 

 

test2.html에서 인클루드한 BOM 없는 파일입니다.

† 급조해서 만들다 보니 img 태그에 alt 속성이 빠졌군요. 접근성 향상을 위해서 꼭 넣어주는 것이 좋습니다. ^^;

첫 번째 이미지 맨 앞에 보이는 세 개의 바이트, EF BB BFtest1.html에 들어가고, IE가 이 BOM을 제대로 해석하지 못하기 때문에 문제가 생기는 것이지요.

BOM 문제를 해결하는 방법

가장 좋은 방법은 BOM을 처음부터 넣지 않는 것입니다. 윈도우즈의 메모장 대신 BOM 설정이 가능한 전문적인 텍스트 에디터를 사용하는 것이 좋겠지요.

 

 

위 이미지는 텍스트 에디터로서 좋은 평가를 받고 있는 에디트플러스BOM 관련 옵션 설정 창입니다.

UTF-8 Signature가 BOM을 가르키는데 선택 가능한 값과 그 의미는 아래와 같습니다.

  • Preserve existing signature: BOM이 있을 경우에만 그대로 유지합니다.
  • Always add signature: 항상 BOM을 넣습니다.
  • Always remove signature: BOM이 있으면 무조건 제거합니다.
  • Add signature if necessary: 필요할 경우에만 BOM을 넣습니다.

여기에서 ‘Always remove signature’로 지정하면 편집하는 모든 파일의 BOM이 제거됩니다.

다른 텍스트 에디터에도 비슷한 설정이 있는 경우가 많습니다.

예를 들어서 프리웨어 텍스트 에디터인 Notepad++는 옵션 설정 창의 ‘New Document’ 탭에서

인코딩 방식을 UTF-8 without BOM으로 설정하면 BOM이 없는 UTF-8 문서를 만들 수 있습니다.

마치며

지금껏 제 경험으로는 UTF-8 문서에서 BOM이 필요했던 경우는 없었습니다.

하지만 특정한 환경에서는 필요할 수도 있으니 상황에 따라 적절히 적용하는 것이 좋습니다.

여담이지만 처음 웹 표준을 접하고 홈페이지를 만들 때 웹 저작 툴인 마이크로 소프트익스프레션 웹 배타판을 사용했는데 CSS에서 * { margin: 0; padding: 0; }을 지정해도 여백이 생겨서 한참 헤맸었습니다. 알고보니 익스프레션 웹이 자동으로 넣은 BOM 때문이더군요.

 

출처: http://blog.wystan.net/2007/08/18/bom-byte-order-mark-problem


 


 

 

[ BOM Remover - Java Version]

 

/**

  *  귀찮아서 그냥 만들었다. 파일 경로만 수정해주면 잘 동작한다.

  **/

 

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BOMRemoverMain
{
 public static void main(String[] args) throws IOException
 {
        String filePath = "C:\\test2.java";
        File file = new File(filePath);   
  
        if (file != null)
        {   
            // BOM 이 존재한다면 BOM을 제거하여 새로운 파일을 작성한다.(UTF-8)   
            DataInputStream dataInputStream = new DataInputStream(new FileInputStream(filePath));       
            int firstChar = dataInputStream.readByte();   
            int secondChar = dataInputStream.readByte();   
            int thirdChar = dataInputStream.readByte();   
               
            if ((firstChar == -17) && (secondChar == -69) && (thirdChar == -65))
            {   
                DataOutputStream dataOutputStream = new DataOutputStream(

                                                                            new FileOutputStream(filePath+"_nobom"));       
                int i;   
                while ((i = dataInputStream.read()) != -1) {   
                    dataOutputStream.writeByte(i);   
                }   
                dataOutputStream.close();   
                file = new File(filePath+"_nobom");   
            }   
            dataInputStream.close();   
        } 
 }
}