ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 18. 파일 입출력 (3) - 파일 읽기
    자바(Java) 강의 2019. 6. 9. 09:46

    이 포스트에서는 자바의 파일 관련 유틸리티 클래스를 이용해 파일 읽기를 하는 방법에 대해 설명한다. 

    이전 포스트

    목표

    • FileReader를 이용해 파일 읽기
    • BufferedReader를 이용해 파일읽기
    • Scanner를 이용해 파일읽기
    • DataInputStream을 이용해 파일읽기
    • Java 8 : java.nio 클래스를 이용해 파일읽기

    프로젝트 구조

    FileTutorial
    ├── FileTutorial
    .iml ├── my_first_file.txt
    └── src
    └── Main
    .java

    1 directory, 2 files

    my_first_file.txt

    파일 쓰기 java Hello World

    FileReader를 이용해 파일 읽기

    FileReader는 char배열에 읽은 파일을 담아온다.

    import java.io.FileReader;
    import java.io.IOException;

    public class Main {

    public static void main(String[] args) throws IOException {
    String fileName = "my_first_file.txt";

    char[] contents = new char[10];
    FileReader fileReader = new FileReader(fileName);
    fileReader.read(contents);
    fileReader.close();
    System.out.println(contents);
    }
    }
    //결과 파일 쓰기 java

    왜 Hello World는 출력되지 않는가? contents의 길이가 10밖에 되지 않아서이다. 길이를 25로 늘려보자. 어떻게 되는가?

    파일 쓰기 java Hello World

    보일지 모르겠지만 World뒤에 남는 공간에는 공백문자같은것이 들어간다.

    FileReader를 이용하면 이렇게 배열의 크기 등등을 고려해야하므로 신경써야 할 게 많다. 더 간단한 방법이 있을까?

    BufferedReader를 이용한 파일 읽기

    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;

    public class Main {

    public static void main(String[] args) throws IOException {
    String fileName = "my_first_file.txt";

    BufferedReader fileReader = new BufferedReader(new FileReader(fileName));
    String line = fileReader.readLine();
    fileReader.close();
    System.out.println(line);

    }
    } //파일 쓰기 java Hello World

    Scanner를 이용한 파일 읽기

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Scanner;

    public class Main {

    public static void main(String[] args) throws IOException {
    String fileName = "my_first_file.txt";

    Scanner scanner = new Scanner(new File(fileName));
    String content = scanner.next();
    System.out.println(content);
    content = scanner.next();
    System.out.println(content);
    content = scanner.next();
    System.out.println(content);
    content = scanner.next();
    System.out.println(content);
    content = scanner.next();
    System.out.println(content);
    content = scanner.next();
    System.out.println(content);
    content = scanner.next();
    System.out.println(content);
    }
    }
    // 결과 파일 쓰기 java Hello World Bye World

    이전에 Scanner scan = new Scanner(System.in)을 사용해 키보드라는 입력 장치에서 입력을 받았던 적이 있다. 마찬가지로 파일을 이용해 입력을 받을 수 있다. 위의 예제에서도 볼 수 있듯이 next 메서드를 부르면 프로그램이 파일을 탐색하는 위치에서부터 첫번째 스페이스까지의 단어를 리턴한다. 이후 파일을 탐색하는 위치가 바로 리턴 직전 스페이스가 있던 곳이 된다. 어떤 글을 줄을 쳐 가면서 읽는다고 생각하면 이해가 쉽다. 왼쪽에서 오른쪽으로 줄을 치며 읽는것이다. 이때 줄을 치고 있는 펜이 있는 위치가 파일을 탐색하는 위치이다. 이렇게 Scanner가 파일을 읽기위해 끊는 위치를 'delimiter', 한국어로는 경계기호라고 한다. Delimiter가 꼭 스페이스일 필요는 없다. useDelimiter라는 메서드를 이용하면 본인이 원하는 위치에서 끊을 수 있다.

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Scanner;

    public class Main {

    public static void main(String[] args) throws IOException {
    String fileName = "my_first_file.txt";

    Scanner scanner = new Scanner(new File(fileName));
    scanner.useDelimiter("\n");
    String content = scanner.next();
    System.out.println(content);
    content = scanner.next();
    System.out.println(content);
    }
    }
    // 실행 결과 파일 쓰기 java Hello World Bye World

    '\n'은 줄바꿈을 의미한다. useDelimiter("\n")은 즉 줄바꿈 전까지 파일을 읽으라는 뜻이다. next를 처음 부르면 첫번째 줄을 리턴하고 위치는 그 다음줄이 된다.

    DataInputStream을 이용해 파일 읽기

    import java.io.*;

    public class Main {

    public static void main(String[] args) throws IOException {
    String fileName = "my_first_file.txt";
    DataOutputStream writer = new DataOutputStream(new FileOutputStream(fileName));
    writer.writeUTF("Writing to file..");
    writer.close();
    DataInputStream reader = new DataInputStream(new FileInputStream(fileName));
    String content = reader.readUTF();
    reader.close();

    System.out.println(content);
    }
    }
    // 실행 결과 Writing to file..

    DataInputStream을 이용하면 파일 전체 내용을 한꺼번에 가져올 수 있다. 주의할 점은 파일이 UTF로 인코딩 되어있어야 한다는 것이다. 하지만 readUTF가 아니더라도 readByte, readChar등 여러가지 읽기 메서드를 제공하므로 이를 이용할 수 있다.

    예를들어 아래의 메서드를 보자.

    my_first_File.txt내용을 아래처럼 변경하자.

    Hello World


    import java.io.*;

    public class Main {

    public static void main(String[] args) throws IOException {
    String fileName = "my_first_file.txt";
    DataInputStream reader = new DataInputStream(new FileInputStream(fileName));
    byte[] bytes = new byte[10];
    reader.read(bytes);
    String content = new String(bytes);
    reader.close();

    System.out.println(content);
    }
    }
    //실행 결과 Hello Worl

    위처럼 bytes에 받아오면 배열의 크기반큼 받아올 수 있다.

    Java 8 : java.nio 클래스를 이용해 파일읽기

    import java.io.*;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;

    public class Main {

    public static void main(String[] args) throws IOException {
    String fileName = "my_first_file.txt";
    Path path = Paths.get(fileName);

    BufferedReader reader = Files.newBufferedReader(path);
    String content = reader.readLine();
    System.out.println(content);
    }
    }

    마지막으로 nio 패키지가 제공하는 유틸리티 메서드를 이용해서 파일을 읽을 수 있다.

    이번 포스트에서는 다양한 유틸리티 클래스를 이용해 파일을 읽는 방법에 대해 알아보았다. 요새는 대부분 서버 클라이언트 모델이나 데이터베이스를 사용하므로 파일 읽기 쓰기를 하는 경우는 많지 않을 수 있다. 하지만 파일 입출력을 아는것이 중요한 이유는 파일 뿐만 아니라 다른 입출력 장치들도 비슷한 방법으로 사용할 수 있기 때문이다. 다음 포스트부터는 Generic에 대해 이야기 해 보도록 한다.

    댓글

f.software engineer @ All Right Reserved