La foret rouge
Published on

Java InputStream.read()는 왜 int를 반환할까?

Authors
  • avatar
    Name
    신주용

InputStream

Java의 InputStream 클래스는 추상 클래스로, 표준 입력, 파일, 네트워크 등에서 입력을 받는 Java 클래스는 이 클래스를 상속받아 구현합니다.12.

int read()

Oracle Java8 InputStream.read()

Oracle Java8 문서에 따르면 InputStream을 사용해 데이터를 읽을 때 input stream으로부터 read() 메소드를 사용해 1바이트 (0~255 (00~FF)) 단위로 읽습니다. 그리고 반환 타입인 int(4바이트)의 마지막 1바이트에 방금 읽은 데이터를 넣어 반환하고, 데이터 읽는데 실패하면 -1을 반환합니다.

바이트를 읽으려는데 왜 반환 타입은 int인가요?

그런데, 1바이트만 읽어서 반환하는거면 byte 타입으로 반환하면 되지 않나요? 왜 int read()인가요? int는 byte보다 4배나 많은 공간을 사용하는데..? 🧐 이 내용을 저는 여러 자료13를 참고해 다음과 같이 이해했습니다.

  1. ASCII, UTF-8도 데이터를 0부터 표시하므로 바이트 데이터 자체가 음수인 경우는 없습니다.
  2. 하지만 자바에 unsigned byte (0~255) 자료형은 따로 없기 때문에 byte (-128~127) 타입으로 읽으면 문제가 생깁니다. 그래서 byte보다 더 큰 범위의 자료형(short, int 등)을 사용해야 합니다.
  3. byte 데이터는 0 이상의 값으로 표현되므로 정상적으로 읽었을 때는 0 이상의 값을 반환합니다. 데이터를 읽는 데 실패하면 음수를 반환하면 되는데, 아무 음수를 반환하는 것이 아니라 -1을 반환하기로 '규칙'을 정했습니다(-1을 2의 보수를 사용해 바이너리로 표현하면 1111).
  4. 결과적으로 반환 타입을 byte가 아니라 4byte int를 사용하고, 데이터 읽는 데 성공 시 마지막 1byte에 방금 읽은 데이터를 포함하여 00 00 00 ??를 반환, 실패 시 (signed) int에서 -1 값을 나타내는 FF FF FF FF를 반환합니다.

왜 short가 아니라 int를 쓰나요?

그러면 int 대신 short read()를 쓰면 더 좋지 않을까요? 4byte인 int에 00 00 00 ??로 저장하는 것보다 2배나 작은 2byte short 타입으로 00 ??와 같이 반환하면 메모리를 훨씬 덜 쓸 것 같은데요?

short를 사용하면 메모리를 절약할 수는 있으나 int가 자바의 기본 정수형 타입이어서 사용한다는 의견이 있었습니다. 여기에 조금 더 깊이 들어가자면 1word와 크기가 맞는 int 타입을 사용하는게 내부 메모리 공간 정렬 문제 등에 있어서 더 효율적이고, short는 연산 시 int로 형변환이 되는 과정이 포함되기 때문에 int를 바로 쓰는게 처리가 빠르다는 의견이 있었습니다34. 다만 int보다 더 큰 타입을 사용하는 경우에는 메모리나 캐시의 대역폭, 처리해야 할 양 증가 등의 문제로 인해 오히려 성능이 더 떨어질 수도 있다고 합니다5.

Prerequisites: 이 글에서 언급되었으나 깊게 설명하지 않은 내용입니다.

  • Java Data Types
  • Java I/O

Footnotes

  1. Oracle. "Class InputStream." docs.oracle.com. https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html (accessed Jul. 30, 2023). 2

  2. Bamdule. "[JAVA] 입출력 스트림 (InputStream, OutputStream)란?" bamdule.tistory.com. https://bamdule.tistory.com/179 (accessed Jul. 30, 2023).

  3. user489041. "Why does InputStream#read() return an int and not a byte?" stackoverflow.com. https://stackoverflow.com/questions/4659659/why-does-inputstreamread-return-an-int-and-not-a-byte/ (accessed Jul. 30, 2023). 2

  4. AnkitSablok. "Issue regarding the return value of the read() function in java?" stackoverflow.com. https://stackoverflow.com/questions/6826875/issue-regarding-the-return-value-of-the-read-function-in-java (accessed Jul. 30, 2023).

  5. UserRR. "C++ int vs long long in 64 bit machine". stackoverflow.com https://stackoverflow.com/questions/39779880/c-int-vs-long-long-in-64-bit-machine (accessed Jul. 30, 2023).