[JAVA] 자바 이진파일 읽기 쓰기 (자바 바이너리 파일을 hex 형태로 읽기 쓰기)

[JAVA] 자바 이진파일 읽기 쓰기 (자바 바이너리 파일을 hex 형태로 읽기 쓰기)

파일은 크게 텍스트 파일과 바이너리 파일로 나눌 수 있다. PDF파일과 같은 바이너리 파일은, 텍스트 형태로 읽어들이고 다시 쓰면 십중팔구 파일이 깨져서 원본 상태로 열리지 않는다.

바이너리 파일을 텍스트 형태로 만들기 위해서는, 파일을 BASE64 로 만드는 방법도 있지만 HEX 문자열 형태로 만드는 방법이 있다. 바이트를 정수(int)로 만들고, 정수를 HEX로 만들면 깨지지 않으며 나중에 원본 그대로 되살릴 수 있다. 바이트 하나가 HEX 2자리가 되므로, 용량은 딱 2배가 된다.

※ 바이트(-128~127)가 정수(int)가 되고, 정수(int)는 HEX가 된다. 최저 -128에서 최고 127까지이므로 HEX는 2자리를 초과할 수 없다.

정수 -128 은 HEX로 80 이 되고, 정수 127 은 HEX로 7F 가 된다.

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

public class JavaBinaryFileToHex {

    public static void main(String[] args) {
        try {
            String originFilePath = “C:\\test\\TODO.pdf”;
            String hexFilePath = “C:\\test\\TODO_hex.txt”;
            String destFilePath = “C:\\test\\TODO_2.pdf”;

            File file = new File(originFilePath);

            // 1. 바이너리 파일을 hex 형태로 읽기
            String hex = readBinaryFileToHex(file);

            // 2. hex 문자열을 텍스트 파일로 쓰기 (확인용)
            writeTextFile(hexFilePath, hex);

            // 3. hex 문자열을 binaryFile로 만들기
            writeBinaryFileFromHex(destFilePath, hex);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 바이너리 파일을 hex 형태로 읽기 (file to hex 문자열)
     *
     * @param file
     * @return
     * @throws IOException
     * @throws Exception
     */

    public static String readBinaryFileToHex(File file) throws IOException, Exception {
        if (file == null || !file.exists()) {
            return null;
        }

        StringBuffer hexBuff = new StringBuffer();

        FileInputStream fileInputStream = null;
        DataInputStream inputStreamReader = null;

        try {
            fileInputStream = new FileInputStream(file);
            inputStreamReader = new DataInputStream(fileInputStream);

            byte[] b = new byte[1024];
            int len = 0; // 실제로 읽어온 길이 (바이트 개수)

            while ((len = inputStreamReader.read(b)) > 0) {
                for (int i = 0; i < len; i++) {
                    hexBuff.append(String.format(“%02X “, b[i]).trim());
                }
            }

        } catch (IOException e) {
            throw e;

        } catch (Exception e) {
            throw e;

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

        return hexBuff.toString();
    }

    /**
     * hex 문자열을 binaryFile로 만들기
     *
     * @param filePath
     * @param hex
     * @return
     * @throws IOException
     * @throws Exception
     */

    public static boolean writeBinaryFileFromHex(String filePath, String hex) throws IOException, Exception {
        if (filePath == null || filePath.length() == 0) {
            return false;
        }

        if (hex == null) {
            hex = “”;
        }

        boolean isWrite = false;

        File file = new File(filePath);

        FileOutputStream fileOutputStream = null;
        DataOutputStream outputStreamWriter = null;

        try {
            boolean isAppend = false;
            fileOutputStream = new FileOutputStream(file, isAppend);
            outputStreamWriter = new DataOutputStream(fileOutputStream);

            int arrayLen = hex.length() / 2;
            int[] b = new int[arrayLen];

            // hex string to int array
            int c = 0;
            int len = hex.length();
            for (int i = 0; i < len; i = i + 2) {
                b[c] = Integer.parseInt(hex.substring(i, i + 2), 16);
                c++;
            }

            // int array to byte
            for (int i = 0; i < b.length; i++) {
                outputStreamWriter.write(b[i]);
            }

            isWrite = true;

        } catch (IOException e) {
            throw e;

        } catch (Exception e) {
            throw e;

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

        return isWrite;
    }

    /**
     * 문자열을 텍스트 파일로 쓰기 (한글 등 인코딩 고려하지 않았음)
     *
     * @param filePath
     * @param content
     * @return
     * @throws IOException
     * @throws Exception
     */

    public static boolean writeTextFile(String filePath, String content) throws IOException, Exception {
        boolean isWrite = false;

        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(filePath);
            fileWriter.write(content);
            isWrite = true;

        } catch (IOException e) {
            throw e;

        } catch (Exception e) {
            throw e;

        } finally {
            close(fileWriter);
        }

        return isWrite;
    }

    private static void close(FileWriter obj) {
        try {
            if (obj != null) {
                obj.close();
            }
        } catch (Exception e) {
        } finally {
            obj = null;
        }
    }

    private static void close(DataOutputStream obj) {
        try {
            if (obj != null) {
                obj.close();
            }
        } catch (Exception e) {
        } finally {
            obj = null;
        }
    }

    private static void close(DataInputStream obj) {
        try {
            if (obj != null) {
                obj.close();
            }
        } catch (Exception e) {
        } finally {
            obj = null;
        }
    }

    private static void close(FileInputStream obj) {
        try {
            if (obj != null) {
                obj.close();
            }
        } catch (Exception e) {
        } finally {
            obj = null;
        }
    }

    private static void close(FileOutputStream obj) {
        try {
            if (obj != null) {
                obj.close();
            }
        } catch (Exception e) {
            obj = null;
        }
    }
}

참고사이트 1 : https://rabbitchris.tistory.com/625

참고사이트 2 : http://mwultong.blogspot.com/2007/04/java-binary-file-write-save.html

참고사이트 3 : http://mwultong.blogspot.com/2007/04/java-read-binary-file.html