Home [Java 프로그래밍] 9강 - java.io 패키지와 스트림
Post
Cancel

[Java 프로그래밍] 9강 - java.io 패키지와 스트림

💡해당 게시글은 방송통신대학교 김희천 교수님의 'Java 프로그래밍' 강의를 개인 공부 목적으로 메모하였습니다.



학습 개요


  • File클래스는 파일과 디렉터리의 생성과 삭제, 정보의 검색과 변경 기능을 제공하나 입출력 기능을 제공하지는 않음
  • Java 언어에서 스트림을 통해 입출력을 수행할 수 있음
  • 입력 스트림과 출력 스트림, 바이트 단위 스트림과 캐릭터 단위 스트림, 기본 스트림과 보조 스트림의 차이를 살펴봄



학습 목표


  • 스트림 개념을 이해하고 종류와 특성을 설명할 수 있음
  • File클래스의 사용법을 설명할 수 있음
  • RandomAccessFile클래스를 사용하여 파일 입출력을 할 수 있음
  • 보조 스트림 클래스를 사용하여 입출력을 할 수 있음



강의록


입출력 스트림

입출력 스트림

  • Java 프로그램에서 스트림을 통해 입출력을 수행할 수 있음
    • 입력 스트림은 데이터 생산자(소스)와 프로그램을 연결
    • 출력 스트림은 프로그램과 데이터 소비자(목적지)를 연결
  • 입출력 종류(파일, 주변 장치, 네트워크 소켓 등)에 상관없이 동일한 방법으로 프로그램을 작성
    • 스트림을 통해 입출력을 제어함
  • 입출력에 필요한 스트림 클래스는 java.io패키지에서 제공
  • 스트림의 정의와 특성
    • 데이터 생상자(또는 데이터 소비자)와 프로그램 사이 데이터의 흐름
    • 순서가 있는 일련의 데이터 흐름으로, 정해진 방향으로 전달되고, 순차적으로 접근할 수 있음

입력 스트림과 출력 스트림

image.png

  • 프로그램은 입력 스트림으로부터 데이터를 읽을 수 있음
    • 외부로부터 데이터를 읽어 프로그램으로 가져오기 위한 스트림
    • 데이터 소스가 설정 되어야 함
  • 프로그램은 출력 스트림으로 데이터를 쓸 수 있음
    • 프로그램에서 데이터를 생성하여 외부로 보내기 위한 스트림
    • 데이터 목적지가 설정되어야 함

스트림의 분류

  • 바이트 스트림과 캐릭터 스트림
    • 바이트 스트림은 byte 단위로 데이터를 다룸
      • 관련 클래스는 xxxInputStreamxxxOutputStream
    • 캐릭터 스트림은 char 단위로 데이터를 다룸
      • 관련 클래스는 xxxReaderxxxWriter
  • 기본 스트림과 보조 스트림
    • 기본 스트림은 입출력 기능을 제공하는 스트림
    • 보조 스트림은 자체적으로 입출력 기능을 수행할 수는 없으며, 기본 스트림과 함께 사용되어 보조 기능을 제공하는 스트림

스트림 관련 클래스

처리 단위처리 방향입력 스트림출력 스트림
기본 스트림바이트 스트림InputStream, FileInputStream, ByteArrayInputStreamOutputStream, FileOutputStream, ByteArrayOutputStream
 문자 스트림Reader, FileReader, CharArrayReader, StringReaderWriter, FileWriter, CharArrayWriter, StringWriter
보조 스트림바이트 스트림BufferedInputStream, DataInputStream, ObjectInputStreamBufferedOutputStream, PrintStream, DataOutputStream, ObjectOutputStream
 문자 스트림BufferedReaderBufferedWriter, PrintWriter
 기타InputStreamReaderOutputStreamWriter

프로그램에서 스트림 사용하기

  • 프로그램에서 어떤 스트림 클래스를 사용할 것인가?

    1
    2
    
      FileInputStream fis = new FileInputStream( );
      BufferedInputStream bis = new BufferedInputStream(fis);
    
    • 입력 스트림? 출력 스트림?
    • 데이터 생산자와 소비자를 결정
      • 기본 스트림을 반드시 사용해야 함
    • 문자 단위? 바이트 단위?
    • 보조 스트림이 필요한가?
      • 필요하다면 기본 스트림 객체를 먼저 생성하고, 기본 스트림을 감싸 보조 스트림 객체를 생성함

바이트 스트림

InputStream클래스

  • 바이트 단위 입력 스트림 클래스 중 최상위 추상 클래스
    • 이것의 하위 클래스는 xxxInputStream
  • 주요 메소드
    • read메소드
      • 입력 스트림으로부터 1 바이트를 읽어 정수로 리턴함

        1
        
          abstract int read( )
        
      • 입력 스트림으로부터 읽어서 byte 배열에 저장하고 읽어 들인 바이트 개수를 리턴

        1
        
          int read(byte[] b)
        
      • len 바이트를 읽어서 바이트 배열의 off 위치부터 저장함

        1
        
          int read(byte[] b, int off, int len)
        
    • available메소드
      • 다음 read()할 때, 블로킹 없이 입력 스트림에서 읽을 수 있는 바이트 단위의 데이터 길이

        1
        
          int available()
        
    • skip메소드
      • 입력 스트림에서 n 바이트를 건너 뜀

        1
        
          long skip(long n)
        
    • mark메소드
      • 입력 스트림에서 현재 위치를 표시함
      1
      
        void mark(int readlimit)
      
    • reset메소드
      • mark()에서 표시 된 위치로 스트림의 현재 위치를 이동

        1
        
          void reset()
        

OutputStream클래스

  • 바이트 단위 출력 스트림 클래스 중 최상위 추상 클래스
    • 이것의 하위 클래스는 xxxOutputStream
  • 주요 메소드
    • write메소드
      • 1 바이트의 데이터를 출력 스트림에 씀

        1
        
          void write(int b)
        
      • byte형 배열 b의 모든 바이트를 출력 스트림에 씀

        1
        
          void write(byte[] b)
        
      • byte형 배열 b의 off 위치부터 len 바이트를 출력 스트림에 씀

        1
        
          void write(byte[] b, int off, int len)
        
    • close메소드
      • 출력 스트림을 닫고 자원을 돌려줌

        1
        
          void close()
        
    • flush메소드
      • 출력 스트림에 남아 있는 모든 데이터를 최종 목적지로 보냄

        1
        
          void flush()
        

Reader클래스

  • 입력용 캐릭터 단위 스트림 클래스 중 최상위 추상 클래스
    • 이것의 하위 클래스는 xxxReader
  • 주요 메소드
    • read메소드
      • 입력 스트림에서 1개 문자(2바이트)를 읽어 리턴함

        1
        
          int read()
        
      • 입력 스트림에서 문자들을 읽어 char형 배열 cbuf에 저장하고, 읽어 들인 문자의 개수를 리턴함

        1
        
          int read(char[] cbuf)
        
    • ready메소드
      • 입력 스트림에 입력 데이터가 준비되었으면 true를 리턴함

        1
        
          boolean ready()
        
    • close메소드
      • 입력 스트림을 닫고 자원을 반환 함

        1
        
          abstract void close()
        

Writer클래스

  • 출력용 캐릭터 단위 스트림 클래스 중 최상위 추상 클래스
    • 이것의 하위 클래스는 xxxWriter
  • 주요 메소드
    • write메소드
      • 1개의 문자(2 바이트)를 출력 스트림에 씀

        1
        
          void write(int c)
        
      • char형 배열 cbuf의 모든 문자를 출력 스트림에 씀

        1
        
          void write(char[] cbuf)
        
      • 문자열 str을 출력 스트림에 씀

        1
        
          void write(String str)
        
      • 문자열 str에서 off 위치부터 len 개의 문자를 출력 스트림에 씀

        1
        
          void write(String str, int off, int len)
        
    • close메소드
      • 출력 스트림을 닫고 자원을 반환함

        1
        
          abstract void close( )
        
    • flush메소드
      • 출력 스트림에 남아 있는 모든 데이터를 최종 목적지로 보냄

        1
        
          void flush( )
        

파일 입출력

File클래스

  • 파일이나 디렉터리를 표현
    • 상대 또는 절대 경로(path)를 가짐
  • 파일이나 디렉터리의 정보 조회 또는 조작 기능을 제공
    • 이름과 경로의 조회
    • 파일과 디렉토리의 생성과 삭제
    • 입출력 메소드는 제공되지 않음
  • 생성자
    • File(String pathname)

      1
      
        File myFile1 = new File("D:\\eclipse\\workspace\\Test\\src");
      
      1
      
        File myFile2 = new File("notepad.exe");
      
      • pathname은 상대 또는 절대 경로로 표현될 수 있음

File클래스의 주요 메소드

  • 주요 메소드
    • exists메소드
      • File객체로 표현된 것이 실제 파일 또는 디렉터리로 존재하는가

        1
        
          boolean exists()
        
    • isDirectory메소드
      • File객체에 지정된 경로가 디렉터리인가

        1
        
          boolean isDirectory()
        
    • isFile메소드
      • File객체에 지정된 경로가 파일인가

        1
        
          boolean isFile()
        
    • getName메소드
      • 파일 또는 디렉터리의 이름을 리턴함

        1
        
          String getName()
        
    • getPath메소드
      • 경로 전체를 리턴함

        1
        
          String getPath()
        
    • length메소드
      • 파일인 경우, 크기를 바이트 단위로 리턴함

        1
        
          long length()
        
    • createNewFile메소드
      • File객체에 지정된 파일을 생성함

        1
        
          boolean createNewFile()
        
    • delete메소드
      • File객체에 지정 된 파일이나 디렉터리를 삭제함

        1
        
          boolean delete()
        
    • mkdir메소드
      • File객체에 지정된 것을 디렉터리로 만듦
      • 맨 마지막 디렉터리만 생성할 수 있음

        1
        
          boolean mkdir()
        
    • mkdirs메소드
      • mkdir메소드와 같으나 지정 된 경로 상의 모든 필요한 디렉터리를 생성

        1
        
          boolean mkdirs()
        
    • list메소드
      • File객체에 지정 된 디렉터리 안에 포함 된 파일과 디렉터리의 이름을 문자열 배열로 리턴함

        1
        
          String[] list()
        
    • listFiles메소드
      • list메소드와 같으나 File객체의 배열로 리턴함

        1
        
          File[] listFiles()
        
    • getParent메소드
      • 상위 디렉터리 이름을 문자열로 리턴함

        1
        
          String getParent()
        
    • getParentFile메소드
      • 상위 디렉터리를 File객체로 리턴함

        1
        
          File getParentFile()
        
    • listRoots메소드
      • 파일 시스템에 존재하는 루트 디렉터리를 File객체의 배열로 리턴함

        1
        
          static File[] listRoots()
        

File클래스 예제

  • 디렉터리 내용 보여주기

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
      import java.io.*;
        
      public class Main {
          public static void main(String args[]) {
              File file = new File("c:\\windows");
              File files[] = file.listFiles();
              int i = 0;
    
              while(i < files.length) {
                  System.out.print(files[i].getPath());
                  System.out.println("\t" + files[i].length());
                  i++;
              }
          }	
      }
        
      // c:\windows\addins 0
      // c:\windows\AgSetup.logs 90624
      // c:\windows\AhnInst.log 2328622
    

RandomAccessFile클래스

  • 랜덤 엑세스 파일
    • 파일의 임의 위치에서 읽기 또는 쓰기 연산을 지원
      • 파일을 오픈하고, 위치를 지정하고, 읽기 또는 쓰기를 함
    • 읽고 쓰는 위치는 파일 포인터가 가리킴
      • 파일 포인터가 가리키는 위치부터 바이트 단위로 읽거나 쓸 수 있음
    • byte 단위로 읽고 쓰며, 읽거나 쓸 때 파일 포인터가 이동 됨
      • 랜덤 엑세스 파일을 커다란 byte 배열로 볼 수 있음

RandomAccessFile클래스의 메소드

  • 생성자

    1
    
      RandomAccessFile(File file, String mode)
    
    1
    
      RandomAccessFile(String name, String mode)
    
    • mode는 읽기 전용의 r또는 읽기/쓰기 겸용의 rw
  • 주요 메소드

    • read메소드
      • 파일로부터 1 바이트를 읽어 리턴함

        1
        
          int read()
        
      • 파일로부터 읽어 byte 배열에 저장함

        1
        
          int read(byte[] b)
        
      • 파일로부터 최대 len 바이트를 읽어 byte형 배열의 off 위치부터 저장함

        1
        
          int read(byte[] b, int off, int len)
        
    • seek메소드
      • pos에 지정 된 위치로 파일 포인터를 이동함

        1
        
          void seek(long pos)
        
    • write메소드
      • byte 배열의 내용을 파일에 씀

        1
        
          void write(byte[] b)
        
      • byte 배열에서 off 위치부터 len 바이트를 파일에 씀

        1
        
          void write(byte[] b, int off, int len)
        

RandomAccessFile클래스 예제

  • RandomAccessFile이용하여 파일에 쓰고 읽기

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
      import java.io.*;
        
      public class Main {
          public static void main(String args[]) {
              try (RandomAccessFile raf = new RandomAccessFile("c:\\java\\test.txt", "rw")) {
                  for(int i = 0; i < 10; i++)
                      raf.write(i);
                
                  for(int i = 9; i >= 0; i--) {
                      raf.seek(i);
                      System.out.print(raf.read( ));
                  }
                    
                      raf.close();
                  } catch (Exception e) { 
                      System.out.println(e); 
                  }
          }
      }
        
      // 9876543210
    

FileInputStreamFileOutputStream클래스

  • 파일로부터 데이터를 읽기/쓰기 위한 입력/출력용 기본 스트림
    • 바이트 단위의 입력/출력을 처리하므로 이미지나 오디오 파일과 같은 이진 파일을 다룰 때 유용함
  • FileInputStream클래스의 생성자
    • 기존 파일과 연결된 입력 스트림 객체를 생성

      1
      
        FileInputStream(File file)
      
      1
      
        FileInputStream(String name)
      
  • FileOutputStream클래스의 생성자
    • 기존 파일(없다면 생성)과 연결된 출력 스트림 객체를 생성

      1
      
        FileOutputStream(String name)
      
      1
      
        FileOutputStream(File file, boolean append)
      

FileOutputStream예제

  • FileOutputStream클래스 사용 예

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
      import java.io.*;
        
      public class Main {
          public static void main(String args[]) {
              File inFile = new File("D:\\01_KNOU\\test.txt"); // 입력 파일 경로 지정
              File outFile = new File("D:\\01_KNOU\\test2.txt"); // 출력 파일 경로 지정
              // try-with-resources 문을 사용해 자원을 자동으로 닫음
              try (
                  InputStream is = new FileInputStream(inFile);
                  OutputStream os = new FileOutputStream(outFile)) {
    
                  int nData;
                  nData = is.read(); // 파일에서 1바이트 읽기
    
                  while(nData != -1) { // 파일 끝까지 반복
                      os.write(nData); // 읽은 바이트를 출력 파일에 쓰기
                      nData = is.read(); // 다음 바이트 읽기
                  }
              } catch (Exception e) {
                  System.out.println(e);
              }
          }
      }
    

FileReaderFileWriter클래스

  • 텍스트 파일을 읽거나 쓰는데 사용되는 기본 스트림
    • 문자 단위로 입력 또는 출력을 처리
  • FileReader클래스의 생성자

    1
    
      FileReader(File file)
    
    1
    
      FileReader(String fileName)
    
  • FileWriter클래스의 생성자

    1
    
      FileWriter(File file)
    
    1
    
      FileWriter(String fileName)
    
    1
    
      FileWriter(File file, boolean append)
    

콘솔 입출력과 보조 스트림

Console클래스

  • 콘솔 입출력을 제공하는 클래스
    • 키보드 입력과 화면 출력을 편리하게 지원
    • 명령 프롬프트 창과 같은 콘솔 환경에서 사용자와의 상호 작용을 지원
  • System.console()을 사용하여 콘솔 객체를 생성함
  • 주요 메소드
    • readLine메소드
      • 콘솔에서 한 라인을 읽음

        1
        
          String readLine()
        
    • readPasssword메소드
      • 콘솔에서 비밀번호를 읽음. 비밀번호를 입력할 때 화면에 보이지 않음

        1
        
          char[] readPasssword()
        
    • writer메소드
      • 콘솔과 연결 된 PrintWriter 객체를 리턴함

        1
        
          PrintWriter writer()
        
    • reader메소드
      • 콘솔과 연결 된 Reader 객체를 리턴함

        1
        
          Reader reader()
        

Console클래스 예제

  • Console클래스를 이용한 입출력

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
      import java.io.*;
        
      public class Main {
          public static void main(String args[]) {
              String name;
              char[] pw;
              Console con = System.console();
            
              System.out.print("name : ");
              name = con.readLine( );
              System.out.print("password : ");
              pw = con.readPassword( );
            
              con.printf("name : %s\n", name);
              con.printf("password : %s\n", new String(pw));
          }
      }
        
      // name : kildong
      // password : 
      // name : kildong
      // password : [C@16d3586
    

보조 스트림

  • 기본 스트림의 성능을 높이거나 편의성을 높이는 보조 기능을 제공하는 스트림
  • 입출력 기능은 기본 스트림을 이용해야 함
  • 기본 스트림 객체를 먼저 생성하고, 이것을 보조 스트림 객체를 생성할 때, 생성자의 인자로 이용함

    1
    2
    
      FileInputStream fis = new FileInputStream("text.txt");
      BufferedInputStream bis = new BufferedInputStream(fis);
    
    • 기본 스트림을 보조 스트림으로 감싼다라고 함
    • 프로그램에서는 보조 스트림 객체를 사용해 입출력하면 됨

보조 스트림의 종류

  • 버퍼링 기능의 제공
    • BufferedInputStream, BufferedOutputStream
    • BufferedReader, BufferedWriter
  • Java의 기본 자료형을 그대로 읽기/쓰기 위한 기능의 제공
    • DataInputStream, DataOutputStream
  • 다양한 출력 형식의 제공
    • PrintStream, PrintWriter
  • 텍스트 파일을 라인 단위로 읽거나 라인 번호를 관리하는 메소드 제공
    • LineNumberReader
  • 바이트 스트림과 캐릭터 스트림의 호환
    • InputStreamReader, OutputStreamWriter

LineNumberReader클래스

  • 텍스트 파일을 라인 단위로 읽어 들이는 메소드 제공

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
      import java.io.*;
        
      public class Main {
          public static void main(String args[]) {
              try (FileReader fr = new FileReader(new File("c:\\Java\\Main.java"));
                  LineNumberReader rd = new LineNumberReader(fr)) {
                  String line;
                    
                  while ((line = rd.readLine()) != null) {
                      System.out.println(line);
                  }
              } catch (Exception e) {
                  System.out.println(e); 
              }
          }
      }
    
  • BufferedReader의 서브 클래스
  • 주요 메소드

    1
    
      int read()
    
    1
    
      String readLine()
    
    1
    
      int getLineNumber()
    
    1
    
      long skip(long)
    

InputStreamReader클래스

  • 바이트 입력 스트림을 캐릭터 입력 스트림으로 변환해 주는 클래스
    • 바이트 단위로 읽히는 스트림을 문자 단위로 읽을 수 있게 함
    • 특정 문자 인코딩을 사용하여 변환할 수 있음
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
      try (InputStreamReader isr = new InputStreamReader(System.in, "euc-kr")) {
          while ((i = isr.read()) != '끝') {
              System.out.print((char) i);
          }
      } catch (Exception e) {
          System.out.println(e);
      }
        
      // abc
      // abc
      // 한국
      // 한국
      // 땅끝
      // 땅
    
    • 바이트 단위로 읽은 후 문자로 바꾸어 처리함
  • 생성자

    1
    
      InputStreamReader(InputStream in, Charset cs)
    
  • 주요 메서드

    1
    
      int read() **//** 1개 문자를 읽어 리턴함
    
    1
    
      int read(char[] cbuf, int offset, int length)
    



학습 정리


  • Java 프로그램에서는 스트림을 통해 데이터 생산자(또는 소비자)의 종류와 무관하게 동일한 방법으로 입력(또는 출력)을 수행할 수 있음
  • File클래스는 파일(또는 디렉터리)를 표현하는 클래스로 파일(또는 디렉터리)를 조작할 수 있는 메소드를 제공하나 입출력 메소드는 제공하지 않음
  • RandomAccessFile클래스는 파일의 읽기/쓰기를 지원하며 파일 포인터가 가리키는 임의의 위치에 읽기/쓰기가 가능함
  • BufferedInputStream(OutputStream)과 BufferedReader(Writer)는 보조 스트림으로 버퍼링 기능을 제공하여 입출력 성능을 향상 시킴
  • 기본 스트림의 객체를 먼저 생성하고, 그 객체를 인자로 하여 보조 스트림 객체를 생성함
  • InputStreamReader는 바이트 단위 입력 스트림을 캐릭터 단위 입력 스트림으로 변환하는 기능을 함



연습 문제


  1. 입력 스트림은 기본 스트림과 보조 스트림으로 나뉜다. 다음 중 기본 스트림에 해당하지 않는 것은?

    a. BufferedReader

    • 기본 스트림에 해당 하는 것은?
      • CharArrayReader
      • FileReader
      • ByteArrayInputStream
  2. BufferedReader 클래스에 관한 설명으로 틀린 것은 무엇인가?

    a. 바이트 단위의 입력 기능을 제공한다.

    • BufferedReader클래스에 관한 설명으로 옳은 것은?
      • Reader의 자식 클래스임
      • read()readLine()등 다양한 입력 메소드를 제공함
      • 입력 과정에 버퍼링 기능을 제공함
  3. 키보드에서 한글을 입력받기 위해서 바이트 단위의 표준 입력 스트림(System.in)을 캐릭터 스트림으로 변환하는 것이 필요하다. 다음 밑줄 부분에 공통으로 들어갈 클래스 이름은 무엇인가?

    1
    2
    3
    4
    5
    6
    
     _____ isr = new _____ (System.in);
        
     try {
     	int i = isr.read( );
     	System.out.println((char) i);
     }
    

    a. InputStreamReader

[데이터 정보 처리 입문] 9강 - 엑셀을 이용한 그래프 그리기 2

[파이썬 프로그래밍 기초] 9강 - 함수