안드로이드 텍스트(text) 파일 입출력 1. [File, FileWriter, FileReader, BufferedWriter, BufferedReader] (Android Text File I/O 1)

2017. 2. 23. 14:41


1. 바이너리(binary) 파일과 텍스트(text) 파일 입출력.

이전 글 [안드로이드 바이너리(binary) 파일 입출력 1]에서, 안드로이드(Java)에서 사용할 수 있는 기본적인 파일 입출력 방법에 대해 설명하였습니다. FileInputStream과 BufferedInputStream을 사용하여 파일로부터 데이터를 읽어들이는 방법 및 코드, 그리고 FileOutputStream과 BufferedOutputStream을 사용하여 파일에 데이터를 쓰는 방법과 예제 코드를 살펴보았죠.


그런데 FileInputStream과 FileOutputStream을 사용함에 있어, 경우에 따라 추가적인 작업을 수행해야 하는 번거로운 상황이 발생할 수 있습니다. byte(또는 byte[]) 단위로 처리되어야 하는, 바이너리(binary) 파일을 읽고 쓸 때는 별 다른 이슈가 없지만, char(또는 String) 단위로 처리되어야 하는 텍스트(text) 파일을 다루기 위해서는 byte(또는 byte[])와 char(또는 String) 간 타입 변환을 무조건 해줘야 하는 문제가 있죠. 게다가 읽어들인 버퍼 인덱스의 경계에 따라 타입 변환으로도 잘못된 데이터를 가져오게 되는 문제가 생길 수 있습니다.


이러한 이슈로 인해 텍스트(text) 파일을 읽고 쓸 때는 FileInputStream 또는 FileOutputStream을 사용하지 않고, 텍스트(text) 파일 입출력을 위해 별도로 제공되는 클래스를 사용합니다.


바로 FileWriter와 FileReader 클래스입니다.

2. 텍스트(text) 파일 입출력. (FileWriter, FileReader)

파일을 다루는 다른 여러 클래스와 마찬가지로, FileWriter와 FileReader 또한 "java.io" 패키지에 구현되어 있습니다.

FileWriter, FileReader 클래스


사용 방법 자체는 앞서 살펴보았던 FileOutputStream 또는 FileInputStream 클래스와 크게 다르지 않습니다. 하지만 read() 또는 write() 함수를 통해 다루는 데이터는 그 성질이 다르죠.


그럼 먼저, FileWriter를 사용하여 파일로부터 데이터를 쓰는 방법부터 살펴보도록 하겠습니다.

2.1 텍스트(text) 파일 쓰기. (FileWriter)

FileWriter 클래스를 사용하여 데이터를 쓰는 코드는 다음과 같습니다.

FileWriter 파일 쓰기 과정


FileWriter 클래스를 사용하여 파일에 텍스트(text) 데이터 쓰기
    File file = new File("file.txt") ;
    FileWriter fw = null ;
    String text = "This is TEST string." ;

    try {
        // open file.
        fw = new FileWriter(file) ;

        // write file.
        fw.write(text) ;

    } catch (Exception e) {
        e.printStackTrace() ;
    }

    // close file.
    if (fw != null) {
        // catch Exception here or throw.
        try {
            fw.close() ;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.2 텍스트(text) 파일 읽기. (FileReader)

FileReader 클래스를 사용하여 텍스트를 읽는 코드는 아래와 같습니다.

FileReader 파일 읽기 과정


FileReader 클래스를 사용하여 파일로부터 한 글자 텍스트(text) 데이터 읽기
    File file = new File("file.txt") ;
    FileReader fr = null ;
    int data ;
    char ch ;

    try {
        // open file.
        fr = new FileReader(file) ;

        // read file.
        while ((data = fr.read()) != -1) {
            // TODO : use data
            ch = (char) data ;
            System.out.println("ch : " + ch) ;
        }

        fr.close() ;
    } catch (Exception e) {
        e.printStackTrace() ;
    }

위의 코드는 파일("file.txt")을 열어 파일의 끝에 도착할 때까지 루프를 돌며 1 문자 씩 읽어들이는 코드입니다. 이러한 방법은 [안드로이드 바이너리(binary) 파일 입출력 1]에서 잠시 언급한 것처럼, 성능면에서 그다지 효율적이지 않습니다.

효율적인 데이터 입출력을 위해서는 문자를 하나 씩 읽지 않고, 충분한 버퍼 길이만큼 읽어서 처리하는 게 좋습니다. 이를 위해 다음과 같은 형태의 read() 함수를 사용합니다.

    int read (char[] cbuf) ;

위의 read() 함수는 파일로부터 배열 cbuf의 크기(cbuf.length)만큼 데이터를 읽은 다음, 읽은 데이터의 크기를 리턴합니다. 만약 파일의 끝까지 읽어들여서 더 이상 읽을 데이터가 없다면, -1이 리턴됩니다. 배열의 크기만큼 텍스트 파일을 읽는 read() 함수는 다음과 같이 사용할 수 있습니다.

FileReader 클래스를 사용하여 파일로부터 버퍼 단위 텍스트(text) 데이터 읽기
    File file = new File("file.txt") ;
    FileReader fr = null ;
    char[] cbuf = new char[512] ;
    int size = 0 ;

    try {
        // open file.
        fr = new FileReader(file) ;

        // read file.
        while ((size = fr.read(cbuf)) != -1) {
            // TODO : use data
            System.out.println("read size : " + size) ;
            for (int i=0; i<size; i++) {
                System.out.println("data : " + cbuf[i]) ;
            }
        }

        fr.close() ;
    } catch (Exception e) {
        e.printStackTrace() ;
    }

3. 버퍼를 사용한 향상된 텍스트 파일 입출력. (BufferedWriter, BufferedReader)

[안드로이드 바이너리(binary) 파일 입출력 1]에서 파일 입출력 성능을 향상시키기 위한 방법으로, 버퍼를 사용한 입출력 방법을 소개하였습니다. BufferedOutputStream과 BufferedInputStream 클래스의 사용이 바로 그것이었죠.


텍스트 파일 입출력의 경우에도 버퍼 관리를 통한 향상된 파일 입출력 방법을 사용할 수 있습니다. 이는 BufferedWriter와 BufferedReader 클래스를 통해 수행할 수 있으며, BufferedOutputStream 또는 BufferedInputStream 클래스를 사용할 때와 비슷한 방법으로 사용할 수 있습니다.

BufferedWriter, BufferedReader 클래스


3.1 버퍼를 이용한 텍스트 파일 쓰기. (BufferedWriter)

BufferedWriter 클래스를 사용하여 파일에 문자열을 쓰는 방법은, 바이너리 데이터를 쓰기 위해 BufferedOutputStream 클래스를 사용하는 방법과 유사합니다.


먼저 FileWriter의 객체를 통해 BufferedWriter의 객체를 생성합니다.

    FileWriter fw = new FileWriter("file.txt") ;
    BufferedWriter bufwr = new BufferedWriter(fw) ;

그리고 BufferedWriter의 write() 함수를 사용하여 문자 또는 문자열 또는 문자 배열을 파일에 씁니다.

    // 파일에 'A'라는 문자 쓰기.
    bufwr.write('C') ;

    // 파일에 "STR"이라는 문자열 쓰기.
    bufwr.write("STR") ;

    // 파일에 {'A', 'R', 'R'} 문자 배열 쓰기.
    bufwr.write(new char[]{'A', 'R', 'R'}) ;

쓰기 과정을 모두 완료했다면, close() 함수를 호출하여 파일 쓰기를 종료합니다. close() 함수를 호출하고나면, 더 이상 write() 함수를 사용하여 파일에 데이터를 쓸 수 없습니다.

    // BufferedWriter 닫기.
    bufwr.close() ;

    // FileWriter 닫기.
    fw.close() ;

위의 과정을 전체 코드로 나타내면 아래와 같습니다.

BufferedWriter 클래스를 사용하여 파일에 텍스트(text) 데이터 쓰기
    File file = new File("file.txt") ;
    FileWriter fw = null ;
    BufferedWriter bufwr = null ;

    String str = "STR" ;

    try {
        // open file.
        fw = new FileWriter(file) ;
        bufwr = new BufferedWriter(fw) ;

        // write data to the file.
        bufwr.write(str) ;

    } catch (Exception e) {
        e.printStackTrace() ;
    }

    // close file.
    try {
        if (bufwr != null)
            bufwr.close() ;

        if (fw != null)
            fw.close() ;
    } catch (Exception e) {
        e.printStackTrace();
    }

4.2 버퍼를 이용한 텍스트 파일 읽기. (BufferedReader)

버퍼를 이용하여 파일로부터 문자열을 읽을 때는 BufferedReader 클래스를 사용합니다.


BufferedReader의 생성 절차는 아래와 같습니다.

    FileReader fr = new FileReader("file.txt") ;
    BufferedReader bufrd = new BufferedReader(fr) ;

그리고 BufferedReader의 읽기와 관련된 함수를 사용하여 파일로부터 문자열 데이터를 읽어들일 수 있습니다.

    // 파일로부터 문자(char) 데이터 읽기.
    char ch = (char)bufrd.read() ;    // 파일로부터 문자(char) 읽기.

    // 파일로부터 문자 배열(char []) 읽기. offset(0)부터 len(cbuf.length)만큼 읽기.
    char cbuf[] = new char[10] ;
    bufrd.read(cbuf, 0, cbuf.length) ;

    // 파일로부터 한 라인 읽기.
    String str = bufrd.readLine() ;

파일 쓰기와 마찬가지로, 읽기 과정이 완료되면 close() 함수를 호출하여 BufferedReader와 FileReader의 객체를 닫습니다.

    // BufferedReader 닫기.
    bufrd.close() ;

    // FileReader 닫기.
    fr.close() ;

아래의 소스 코드는 BufferedReader를 사용하여 파일로부터 한 문자(char) 씩 읽어들이는 코드를 나타낸 것입니다.

BufferedReader 클래스를 사용하여 파일로부터 텍스트(text) 데이터 읽기
    File file = new File("file.txt") ;
    FileReader fr = null ;
    BufferedReader bufrd = null ;

    char ch ;

    try {
        // open file.
        fr = new new FileReader(file) ;
        bufrd = new BufferedReader(fr) ;

        // read 1 char from file.
        while ((ch = bufrd.read()) != -1) {
            System.out.println("char : " + ch) ;
        }

        // close file.
        bufrd.close() ;
        fr.close() ;
    } catch (Exception e) {
        e.printStackTrace() ;
    }

5. 참고.

.END.


ANDROID 프로그래밍/FILE