본문 바로가기
Java

[Java] File 클래스(2)

by bkuk 2022. 10. 13.

InputStream

바이트 단위로 읽는 스트림 중 최상위 스트림이며,

추상 메서드를 포함한 추상 클래스로서 하위 스트림 클래스가 상속받아 각 클래스 역활에 맞게 추상 메서드 기능을 구현하고 있습니다.

스트림 클래스 설명
FileInputStream 파일에서 바이트 단위로 자료를 읽음.
ByteArrayInputStream byte 배열 메모리에서 바이트 단위로 자료를 읽음.
FilterInputStream 기반 스트림에서 자료를 읽을 떄 추가 기능을 제공하는 보조 스트림의 상위 클래스

 

InputStream 클래스에서 제공하는 메서드

메서드 설명
int read() 입력 스트림으로부터 한 바이트의 자료를 읽음. 읽은 자료의 바이트 수를 반환
int read( byte[] b) 입력 스트림으로부터 b[] 크기의 자료를 b[]에 읽음. 읽은 자료의 바이트 수를 반환
int read( byte[] b, int off, int len) 입력 스트림으로부터 b[] 크기의 자료를 b[]의 off 변수 위치부터 저장하며 len만큼 읽음.
읽은 자료의 바이트 수를 반환
void close() 입력 스트림과 연결된 대상 리소스를 닫음. FileInputStream인 경우 파일을 닫음.

 

read() 메서드의 반환형은 int이며, 한 바이트를 읽어서 int에 저장합니다.

더 이상 읽어 들일 자료가 없는 경우 정수 -1이 반환되며, 파일에서 자료를 읽는 경우 파일의 끝을 도달하면 -1이 반환됩니다.

 

 

FileInputStream

파일에서 바이트 단위로 자료를 읽어 들일 때 사용하는 스트림 클래스.

생성자 설명
FileInputStream( String name) 파일 이름 name( 경로 포함)을 매개변수로 받아 입력 스트림 생성
FileInputStream ( File f ) File 클래스 정보를 매개변수로 받아 입력 스트림 생성

FileInputStream 사용하기

 

 

FileInputStream fis = null; //자원 해제 전 객체가 null 인지 여부를 체크해야함.

try {
    // 파일 열기
    fis = new FileInputStream( "./test.txt" );

    int data1 = fis.read();	// 바이트(한 글자) 단위로 읽으며, 아스키 코드로 출력
    System.out.println( data1 );	// 97(아스키 코드)
    System.out.println( (char) data1 );	// a

    data1 = fis.read();	// 다음 글자 읽기
    System.out.println( (char) data1 );	// b
} catch (FileNotFoundException e) {
    System.out.println( e.getMessage() );
} catch (IOException e) {
    System.out.println( e.getMessage() );
} finally {
    // 파일 닫기, 통상적으로 이런 형식으로 기술
    // try 블록에서 Exception이 발생할 수 있으므로 finally 블록에서 자원을 해제해야함.
    if( fis != null) try { fis.close(); } catch ( IOException e){
    }
}

read() 메서드를 사용한 만큼의 바이트만 출력합니다. 위 예제에서는 read() 메서드를 2번 사용했고, 1번째 사용했을 떄 data1을 출력해서 97(아스키 코드)가 출력되었고, 자료형을 char으로 명시적 형변환 해줌으로써 'a' 문자가 출력됨.

 

파일 끝까지 읽기 예제

FileInputStream fis = null;

try {

    fis = new FileInputStream( "./test.txt" );

    int data = 0;
    while( (data = fis.read()) != -1 ) {

        if( data == '\r') {
            System.out.println( "(r)" );
        } else if(data == '\n') {
            System.out.println( "(n)");
        } else {
        System.out.print( (char)data);
        }
    }

} catch (FileNotFoundException e) {
    System.out.println( e.getMessage() );
} catch (IOException e) {
    System.out.println( e.getMessage() );
} finally {
    if( fis != null) try { fis.close(); } catch ( IOException e){
    }
}

 

read() 메서드의 반환형은 int이며, 한 바이트를 읽어서 int에 저장합니다.더 이상 읽어 들일 자료가 없는 경우 정수 -1이 반환되므로 if문을 통해 메모장에 적혀있던 내용을 전부 출력했습니다.

* 한글을 바이트 단위로 읽어 왔을 떄 발생하는 문자 깨짐현상. 문자 스트림을 사용해야함. 다음 포스팅에서 설명할 예정

 

FileOutputStream fos = null;
// 파일을 읽을 때(Input)는 없으면 Exception이 발생하지만, 파일을 쓸 때(Ouput)는 없으면 만든다.

try {
    fos = new FileOutputStream( "./newtest.txt");

    fos.write( 49 );	// 문자 1 에 대응하는 아스키코드는 49
    fos.write( 97 );	// 문자 a에 대응하는 아스키 코드를 넣음.
    fos.write( 'a' );	// 아스키 코드가 아닌 문자를 넣으려면 작은 따옴표로
    fos.write( '\n' );	// 엔터키는 \n
    fos.write( 'b' );	

    System.out.println( "출력 완료" );
} catch (FileNotFoundException e) {
    System.out.println( e.getMessage());

} catch (IOException e) {
    System.out.println( e.getMessage());

} finally {
    if( fos != null ) try { fos.close(); } catch(IOException e) {}
}

 

컴파일 할 때마다 이전에 만든 메모장에 이어서 붙이고 싶다면?

 

생성자에 true를 넣어주고 컴파일 할 때마다 이어서 저장됨.

 

Buffered 스트림

입출력이 한 바이트나 문자 단위로 이루어지면 그만큼 프로그램 수행 속도가 느려집니다. Buffered 스트림은 내부적으로 8,192바이트 크기의 배열을 가지고 있으며 이미 생성된 스트림에 배열 기능을 추가해 더 빠르게 입출력을 실행시킬 수 있도록 버퍼링 기능을 제공합니다.

스트림 클래스 설명
BufferedInputStream 바이트 단위로 읽는 스트림에 버퍼링 기능을 제공
BufferedOutputStream 바이트 단위로 출력하는 스트림에 버퍼링 기능을 제공
BufferedReader 문자 단위로 읽는 스트림에 버퍼링 기능을 제공
BufferedWriter 문자 단위로 출력하는 스트림에 버퍼링 기능 제공

 

버퍼링 기능을 제공하는 스트림 역시 보조 스트림으로 다른 스트림을 포함하여 수행합니다.

생성자 설명
BufferedInputStream(InputStream in) InputStream 클래스를 생성자의 매개변수로 받아 BufferedInputStream을 생성합니다.
BufferedInputStream(InputStream in, int size) InputStream 클래스와 버퍼 크기를 생성자의 매개변수로 받아 BufferedInputStream을 생성합니다.
BufferedOutputStream bos = null;

try {
    bos = new BufferedOutputStream( new FileOutputStream("./newtest.txt"));

    bos.write( 'a' );
    System.out.println( "입력 완료");
} catch (FileNotFoundException e) {
    System.out.println( e.getMessage());
} catch (IOException e) {
    System.out.println( e.getMessage());
} finally {
    if( bos != null ) try { bos.close(); } catch( IOException e) {}
}

 

 

 

 

 

위처럼 바이트 단위로 자료를 읽을 때 깨졌던 한글 문자를 

문자 단위로 출력하는 스트림에 버퍼링 기능을 제공하는 BufferedOutputStream을 생성함으로써 해결

BufferedReader br =null;
try {
    br = new BufferedReader( new FileReader( "./test.txt" ) );
    String str = null;
    while( (str = br.readLine()) != null) {
        System.out.println( str );
    }
} catch (FileNotFoundException e) {
    System.out.println( e.getMessage() );
} catch (IOException e) {
    System.out.println( e.getMessage() );
} finally {
    if( br != null ) try { br.close(); } catch(IOException e) {}
}

댓글