Java

[Java] ByteArrayStream

dev_roach 2022. 3. 28. 22:56
728x90

ByteArrayStream

** ByteArrayInputStream / ByteArrayOutputStream ** 은 메모리에 데이터를 입출력하는데 이용하는 스트림이다.

  • 예시코드
public class ByteArrayInputAndOutputStreamExample {

    public static void main(String[] args) {
        byte[] inSrc = {0,1,2,3,4,5,6};
        byte[] outSrc = null;

        ByteArrayInputStream inputStream = new ByteArrayInputStream(inSrc);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        int data;

        /**
         * read() Method 는 1 Byte 씩 읽어오는 역할을 한다.
         * -1 의 경우는 읽어올 데이터가 없는 경우를 뜻한다.
         */
        while ((data = inputStream.read()) != -1) {
            outputStream.write(data);
        }

        outSrc = outputStream.toByteArray();

        System.out.println(Arrays.toString(inSrc));
        System.out.println(Arrays.toString(outSrc));
    }

}
  • 특징

    • ByteArrayStream 은 위에서 언급했듯이 메모리에 입출력을 하기 때문에 GC 의 관리 대상이 된다. 따라서 close() 를 이용해서 닫지 않아도 된다.
  • 배열을 이용한 ByteStream 최적화

    private static final int BUFFER_SIZE = 4;

    public static void main(String[] args) {

        byte[] inSrc = {0,1,2,3,4,5,6};
        byte[] buffer = new byte[BUFFER_SIZE];
        byte[] outSrc = null;

        ByteArrayInputStream inputStream = new ByteArrayInputStream(inSrc);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        int data;

        System.out.println("Input Source : " + Arrays.toString(inSrc));

        try {
            while (inputStream.available() > 0) {
                /**
                 * read 에 byte[] 를 넣으면 buffer 이다.
                 */
                inputStream.read(buffer);
                outputStream.write(buffer);
                System.out.println("Buffer Pool(Before) : " + Arrays.toString(buffer));

                outSrc = outputStream.toByteArray();
                System.out.println("Buffer Pool(After) : " + Arrays.toString(buffer));
                System.out.println("Output Source : " + Arrays.toString(outSrc));

            }
        } catch (IOException ignored) {}

        System.out.println(Arrays.toString(inSrc)); // [0, 1, 2, 3, 4, 5, 6]
        System.out.println(Arrays.toString(outSrc)); // [0, 1, 2, 3, 4, 5, 6, 3]
    }
  • 문제점
    • 위의 BufferSize 만큼 남는 경우 이상한 값이 들어오게 된다. Buffer read 방식의 경우 기존의 Buffer 를 채워가며 읽는 식인데, 마지막에는 4,5,6 세개만 읽으므로
      기존에 있던 3이 남아있게 된다. 따라서 Buffer 를 어떻게 끊어야 할지 잘 고민해야 한다. 따라서 아래와 같은 방식으로 최적화가 가능하다.
    public static void main(String[] args) {

        byte[] inSrc = {0,1,2,3,4,5,6};

        byte[] outSrc = null;

        ByteArrayInputStream inputStream = new ByteArrayInputStream(inSrc);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        System.out.println("Input Source : " + Arrays.toString(inSrc));

        try {
            while (inputStream.available() > 0) {

                int bufferSize = inputStream.available();
                System.out.println("Blocking 없이 읽어올 수 있는 Byte 수 : " + bufferSize);
                byte[] buffer = new byte[bufferSize];
                /**
                 * read 에 byte[] 를 넣으면 buffer 이다.
                 */
                inputStream.read(buffer);
                outputStream.write(buffer);
                System.out.println("Buffer Pool(Before) : " + Arrays.toString(buffer));

                outSrc = outputStream.toByteArray();
                System.out.println("Buffer Pool(After) : " + Arrays.toString(buffer));
                System.out.println("Output Source : " + Arrays.toString(outSrc));

            }
        } catch (IOException ignored) {}

        System.out.println(Arrays.toString(inSrc)); // [0, 1, 2, 3, 4, 5, 6]
        System.out.println(Arrays.toString(outSrc)); // [0, 1, 2, 3, 4, 5, 6]
    }
728x90