[JAVA] txt 파일 인코딩 확인

[JAVA] txt 파일 인코딩 확인

자바에서 txt 파일 인코딩을 확인하기 위해서는 juniversalchardet 라는 라이브러리를 사용하면 된다고 한다.

본 포스트에서는 라이브러리 없이 단순하게 인코딩을 확인했다.

txt 파일의 일반적인 인코딩은 MS949이며, 본 포스트에서는 MS949 와 UTF-8 이렇게 두 가지 경우의 수만 고려했다.

방법은 먼저 MS949 로 txt 파일을 읽다가, 대체문자(65533)를 발견하면 UTF-8 파일로 판단하여 처음부터 다시 UTF-8로 읽어오는 것이다.

아래 코드에서 readFileMS949orUTF8 메서드를 찾아보면 된다.

참고로 65533 이란 유니코드 대체문자라 부른다. 잘못된 디코더를 적용했을 때, 유효하지 않은 바이트 시퀀스(손상된 바이트 시퀀스)를 대체하기 위한 문자다. 문자열이 깨져 표시되는 물음표를 생각하면 된다.

package com.bb.test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;

public class TestClass {

    public static void main(String[] args) {
        
        new TestClass().main1();
    }
        
    public void main1() {
        
        try {
            File inputFile1 = new File(“C:\\test\\ms949.txt”);
            File inputFile2 = new File(“C:\\test\\utf8.txt”);
            
            // 우선 MS949로 읽는다. 그러다 UTF-8 대체문자(65533)를 발견하면 UTF-8로 읽는다.
            ArrayList<String> fileContent1 = readFileMS949orUTF8(inputFile1);
            ArrayList<String> fileContent2 = readFileMS949orUTF8(inputFile2);
            
            System.out.println(fileContent1);
            System.out.println(fileContent2);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
    /**
     * 우선 MS949로 읽는다. 그러다 UTF-8 대체문자(65533)를 발견하면 UTF-8로 읽는다.
     *
     * @param file
     * @return
     * @throws IOException
     * @throws Exception
     */

    private ArrayList<String> readFileMS949orUTF8(File file) throws IOException, Exception {
        if (file == null || !file.exists()) {
            return null;
        }

        boolean bUTF8 = false;
        ArrayList<String> resultList = null;

        FileInputStream fileInputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;

        try {
            fileInputStream = new FileInputStream(file);
            inputStreamReader = new InputStreamReader(fileInputStream, “MS949”);
            bufferedReader = new BufferedReader(inputStreamReader);

            // 우선 MS949로 읽는다. 그러다 UTF-8 대체문자(65533)를 발견하면 UTF-8로 읽는다.
            int len = 0;
            String oneLine = null;
            while ((oneLine = bufferedReader.readLine()) != null) {
                if (resultList == null) {
                    resultList = new ArrayList<String>();
                }
                
                len = oneLine.length();
                for (int k=0; k<len; k++) {
                    if (((int) oneLine.charAt(k)) == 65533) {
                        bUTF8 = true;
                        break;
                    }
                }
                
                if (bUTF8) {
                    break;
                }

                resultList.add(oneLine);
            }

        } catch (IOException e) {
            throw e;

        } catch (Exception e) {
            throw e;

        } finally {
            close(bufferedReader);
            close(inputStreamReader);
            close(fileInputStream);
        }
        

        // 우선 MS949로 읽는다. 그러다 UTF-8 대체문자(65533)를 발견하면 UTF-8로 읽는다.
        if (bUTF8) {
            return readFile(file, “UTF-8”);
        }

        return resultList;
    }
    
    
    private ArrayList<String> readFile(File file, String charset) throws IOException, Exception {
        if (file == null || !file.exists()) {
            return null;
        }

        ArrayList<String> resultList = null;

        FileInputStream fileInputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;

        try {
            fileInputStream = new FileInputStream(file);
            inputStreamReader = new InputStreamReader(fileInputStream, charset);
            bufferedReader = new BufferedReader(inputStreamReader);

            String oneLine = null;
            while ((oneLine = bufferedReader.readLine()) != null) {
                if (resultList == null) {
                    resultList = new ArrayList<String>();
                }

                resultList.add(oneLine);
            }

        } catch (IOException e) {
            throw e;

        } catch (Exception e) {
            throw e;

        } finally {
            close(bufferedReader);
            close(inputStreamReader);
            close(fileInputStream);
        }

        return resultList;
    }
    
    
    private boolean writeFile(File file, ArrayList<String> stringList, String charset, boolean bAppend) throws IOException, Exception {
        if (file == null) {
            return false;
        }
        
        boolean bWrite = false;

        FileOutputStream fileOutputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        BufferedWriter bufferedWriter = null;

        try {
            fileOutputStream = new FileOutputStream(file, bAppend);
            outputStreamWriter = new OutputStreamWriter(fileOutputStream, charset);
            bufferedWriter = new BufferedWriter(outputStreamWriter);

            if (stringList != null && stringList.size() > 0) {
                String oneLine = null;

                int lineCount = stringList.size();
                int lastIndex = lineCount – 1;

                for (int i = 0; i < lineCount; i++) {
                    oneLine = stringList.get(i);

                    bufferedWriter.write(oneLine, 0, oneLine.length());
                    if (i < lastIndex) {
                        bufferedWriter.newLine();
                    }
                }
            }

            bWrite = true;

        } catch (IOException e) {
            throw e;

        } catch (Exception e) {
            throw e;

        } finally {
            close(bufferedWriter);
            close(outputStreamWriter);
            close(fileOutputStream);
        }

        return bWrite;
    }
    
    
    private static void close(BufferedWriter bufferedWriter) {
        try {
            if (bufferedWriter != null) {
                bufferedWriter.close();
            }
        } catch (Exception e) {
            // 무시

        } finally {
            bufferedWriter = null;
        }
    }
        
        
    private static void close(OutputStreamWriter outputStreamWriter) {
        try {
            if (outputStreamWriter != null) {
                outputStreamWriter.close();
            }
        } catch (Exception e) {
            // 무시

        } finally {
            outputStreamWriter = null;
        }
    }
    
    
    private static void close(FileOutputStream fileOutputStream) {
        try {
            if (fileOutputStream != null) {
                fileOutputStream.close();
            }
        } catch (Exception e) {
            // 무시

        } finally {
            fileOutputStream = null;
        }
    }
    
    
    private static void close(FileInputStream fileInputStream) {
        try {
            if (fileInputStream != null) {
                fileInputStream.close();
            }
        } catch (Exception e) {
            // 무시

        } finally {
            fileInputStream = null;
        }
    }

    
    private static void close(InputStreamReader inputStreamReader) {
        try {
            if (inputStreamReader != null) {
                inputStreamReader.close();
            }
        } catch (Exception e) {
            // 무시

        } finally {
            inputStreamReader = null;
        }
    }
    
    
    private static void close(BufferedReader bufferedReader) {

        try {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        } catch (Exception e) {
            // 무시
            
        } finally {
            bufferedReader = null;
        }
    }
}