ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java I/O <6 - Reader>통계
    언어/자바 2023. 12. 25. 23:25

     

     

    막연하게만 사용하던 I/O를 조금 더 이해해보고자 작성한 글입니다.
    기본적으로 I/O는 O/S 레벨에서 이루어지고 byte를 다룬다는 것을 생각야해합니다.

     


     

     

    Reader

    byte를 다루는 InputStream과 달리 Reader 클래스는 String을 다룰 때 사용되는 클래스이다.
    Reader클래스들은 InputStream을 내부에서 사용하거나 랩핑하여 사용한다.

    Reader = InputStream + String 핸들링

     

     

     

    1. FileReader

    영문을 입력할 때와 한글을 읽을 때를 각각 살펴보자.

      // test.txt
      this is a test sentence
      한글 테스트 입니다.
    
    
      public static void main(String[] args) throws IOException {
        FileInputStream fileStream = new FileInputStream("test.txt");
    
        int data = fileStream.read();
        System.out.println("stream: " + (char) data);
    
        FileReader fileReader = new FileReader("test.txt");
        int res = fileReader.read();
        System.out.println("reader: " + (char) res);
    
      }

     

    - 영문의 경우

    정확히는 ASCII 문자셋에 포함되는 글자를 입력하는 경우이다.
    이때는 두 코드 결과값의 차이가 없다. 왜냐하면 1byte를 읽어도 완성된 문자이고, 1글자를 읽어도 1byte이기 때문이다.

    // text가 "this is a test sentence" 일 경우
    System.out.println("stream: " + (char) data); // t
        
    System.out.println("reader: " + (char) result); // t

     

    - 한글의 경우

    정확히는 유니코드에서 1byte이상으로 표현되는 문자의 경우이다.
    InputStream의 경우는 인코딩결과와 상관없이 1byte를 읽기 때문에 입력한 글자와 다른 글자가 표현되지만, FileReader의 경우는 글자 단위로 읽기 때문에 인코딩을 감안한 byte를 읽는다.

     

    // text가 "한글 테스트 입니다." 일 경우
    System.out.println("stream: " + (char) data); // í
        
    System.out.println("reader: " + (char) result); // 한

     

     

     

    2. InputStreamReader

    다른 Reader클래스를 사용하기 위해 인터페이스 변환이 필요한 경우와 특정 인코딩을 사용하기 위한 경우 2가지에 사용될 수 있다.

     

    - 인터페이스 변환 (브릿징)

    이전 글에서 작성한 소켓 통신 서버 코드이다. String을 다루는 경우 BufferedReader를 사용하면 훨씬 손쉽게 InputStream을 핸들링할 수 있다.
    이 때, BufferedReader는 생성시에 Reader 타입을 인자로 받기 때문에 InputStream을 InputStreamReader 타입으로 변경이 필요하다.

     

    public static void main(String[] args) throws IOException {
          ServerSocket serverSock = new ServerSocket(port);
    
          while(true) {
            Socket socket = serverSock.accept();
    
            InputStream in = socket.getInputStream();
            Reader reader = new InputStreamReader(in); // 인터페이스 변경
            BufferedReader bufReader = new BufferedReader(reader);
    
            String msg = "";
            while((msg = bufReader.readLine()) != null) {
              System.out.println(msg);
            }
    }

     

    - 인코딩 방법 설정

    기본적으로 Reader는 JVM에 설정되있는 encoding방법으로 문자열 처리를 하기 때문에 별도의 encoding 방법을 사용하고 싶다면 InputStreamReader가 필요하다.

      public static void main(String[] args) throws IOException {
        InputStream in = System.in;
        InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
    
        int data = reader.read();
        System.out.println((char) data);
    
      }

     

    InputStreamReader의 2번째 인자로 전달하는 인코딩 방법에 따라 결과가 달라진다.

     

     

     

    3. BufferedReader

    기본 매커니즘은 BufferedInputStream과 같지만, 추가적으로 readLine 메소드를 제공한다.
    문장 단위로 결과를 반환하고, 더이상 문장이 없을 경우 null을 반환한다.

     

    • 파일
    public static void main(String[] args) throws IOException {
    	FileReader reader = new FileReader("./src/ttest.txt");
        BufferedReader bufReader = new BufferedReader(reader);
    
        String data;
        while((data = bufReader.readLine()) != null) {
          System.out.println(data);
        }
    }

     

    • 네트워크
    public static void main(String[] args) throws IOException {
          ServerSocket serverSock = new ServerSocket(port);
    
          while(true) {
            Socket socket = serverSock.accept();
    
            InputStream in = socket.getInputStream();
            Reader reader = new InputStreamReader(in); // 인터페이스 변경
            BufferedReader bufReader = new BufferedReader(reader);
    
            String msg = "";
            while((msg = bufReader.readLine()) != null) {
              System.out.println(msg);
            }
    }

     

     

     

    4.StringReader

    String타입을 글자단위의 바이트로 읽는다.
    언뜻 toCharrArray로 바꿔서 사용할 수도 있다는 생각이 들지만, reader 타입이기 때문에 다른 stream들과 연계하기 사용하기 좋은 이점이 있다.

    public static void main(String[] args) throws IOException {
    	String msg = "한글이다";
        StringReader reader = new StringReader(msg);
    
        int data;
        while ((data = reader.read()) != -1) {
          System.out.println(data);
        }
    }

     

     

     


     

    Summary

    Reader 클래스는 Stream에 String 핸들링 로직을 더해서, String 관련 작업을 편하게 해주는 클래스이다.
    BufferedReader를 사용하면 readLine을 사용할 수 있다.

     

     

     

    '언어 > 자바' 카테고리의 다른 글

    List 정렬에 대하여  (1) 2024.01.12
    Java IO <7 - Writer>  (0) 2023.12.25
    Java I/O <5 - Buffered Stream>  (0) 2023.12.25
    Java I/O <4 - Network Stream>  (1) 2023.12.25
    Java I/O <3 - FileStream>  (0) 2023.12.25
Designed by Tistory.