인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

이석준님의 프로필 이미지

작성한 질문수

김영한의 실전 자바 - 고급 2편, I/O, 네트워크, 리플렉션

문자 다루기4 - BufferedReader

UTF-8 문자열을 char 타입으로 변경하는것에 대해서 궁금합니다.

작성

·

99

·

수정됨

0

public static void main(String[] args) throws IOException {

    String writeString = "가나다ABC";
    System.out.println("writeString = " + writeString);

    // 파일에 쓰기
    var fw = new FileWriter(FILE_NAME, StandardCharsets.UTF_8);
    fw.write(writeString);
    fw.close();

    // 파일에서 읽기
    var content = new StringBuilder();
    var fr = new FileReader(FILE_NAME);
    int ch;
    while ((ch = fr.read()) != -1) {
      char ch1 = (char) ch;
      System.out.println("ch1 = " + ch1);
      content.append(ch1);
    }
    fr.close();
    System.out.println("readString = " + content);
  }

 

질문1) 예제의 코드에서 char ch1 = (char) ch; 로 캐스팅하는부분이 궁금해요

  • 인코딩이 UTF-8 이니 최대 3바이트까지 쓸 수 있는데 이것을 2바이트만쓰는 char 로 캐스팅할 수 있는 이유는 무엇인가요?

    • 가~다 는 자바의 기본인코딩타입인 UTF-16 에서 2바이트로 표현할 수 있기 때문일까요?

    • fr.read() 는 2바이트로 표현해야하는것이 아니라면 해당문자열까지 읽고, 반환하는것으로보이는데 맞는걸까요?

    • 확인해보니 이모지같은경우에는 UTF-16 에서는 두 바이트로 표현이힘들어서 깨지는것을 확인했습니다!

 

질문2) 위의 가정이 맞다면 Reader, Writer 은 항상 JVM이 관리하는 UTF-16 으로 읽는과정이 있으니 byte 단위로 읽는 Stream 보다 성능적으로 느릴 것 같은데 맞을까요?

답변 1

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다.

이석준님, UTF-8 문자열을 char 타입으로 변경하는 것에 대해 문의주셨군요. 질문에 대해 하나씩 답변드리겠습니다.

질문 1) char ch1 = (char) ch;로 캐스팅하는 부분

  • UTF-8 인코딩에서 글자 하나를 나타내기 위해 1바이트에서 4바이트까지 사용될 수 있지만, 코드에서 사용하신 Reader는 기본적으로 UTF-16으로 변환하여 읽어옵니다. 이때, UTF-8 인코딩된 데이터가 Java 내부에서는 UTF-16으로 변환되어 char로 처리됩니다.

    • 말씀하신 것처럼, 한글 가~다와 같은 문자들은 UTF-16에서 2바이트로 표현할 수 있기 때문에 char로 변환이 가능한 것입니다.

    • fr.read() 메서드는 캐릭터 하나를 읽고, 이는 자동적으로 UTF-8에서 UTF-16으로 변환됩니다. 따라서 내부적으로 유니코드 문자 단위로 처리가 되는 것이 맞습니다.

    • 이모지와 같이 UTF-16에서 서러게이트 페어로 표현되어야 하는 문자는 두 바이트로 처리되기 때문에, 단일 char로 처리하기 곤란해집니다. 이에 따라 깨지는 현상을 보신 것으로 보입니다.

질문 2) JVM이 관리하는 UTF-16으로 읽는 Reader, Writer와 Stream의 성능 차이

  • Reader와 Writer는 문자 단위로 데이터를 처리하기 때문에 유니코드 변환 작업이 포함됩니다. 이는 Byte 단위로 처리하는 Stream에 비해 추가적인 변환 작업을 요구하기 때문에 성능적으로 약간의 차이가 있을 수 있습니다.

하지만, Reader와 Writer는 문자열 데이터를 더 직관적으로 다루기 위해 설계되어 있어, 유니코드 문자 기반의 입출력 작업에서는 자연스러운 선택입니다. 성능 차이는 코드 설계 및 데이터 크기 등에 의존할 수 있기 때문에 실제 사용 시 이러한 측면을 함께 고려하는 것이 좋습니다.

추가 정보는 Spring Boot Reference Documentation에서 IO와 관련된 유틸리티와 통합에 관한 자료를 참고하실 수 있습니다.

도움이 되셨길 바랍니다. 다른 질문이 있으시면 언제든지 문의해주세요. 감사합니다!