[Java] 파일 입출력

2022. 8. 4. 03:12·Language/Java
728x90

파일 쓰기

import java.io.FileOutputStream;
import java.io.IOException;

public class Sample {
    public static void main(String[] args) throws IOException {
        FileOutputStream output = new FileOutputStream("c:/out.txt");
        output.close();
    }
}

위 예제를 실행해 보면 c:/ 디렉토리 바로 밑에 새로운 파일(out.txt)이 하나 생성되는 것을 확인할 수 있을 것이다.

※ 맥(Mac)이나 유닉스에서 실행할 경우 c:/ 디렉터리가 없으므로 디렉터리명을 적절하게 변경하여 실행하도록 한다.

파일을 생성하기 위해 FileOutputStream 클래스를 사용했다. FileOutputStream 객체를 생성하기 위해서는 생성자의 입력으로 파일명을 넘겨주어야 한다. 위 예제에서는 경로를 포함하여 c:/out.txt라는 파일명을 생성자의 입력으로 전달하였다.

위의 예에서보면 output.close()라는 문장이 있는데 이것은 사용한 파일 객체를 닫아주는 것이다. 사실 이 문장은 생략해도 된다. 왜냐하면 자바 프로그램이 종료할 때 사용한 파일 객체를 자동으로 닫아주기 때문이다. 하지만 직접 사용한 파일을 닫아주는 것이 좋다. 사용했던 파일을 닫지 않고 다시 사용하려고 할 경우에는 오류가 발생하기 때문이다.

FileOutputStream

생성하는 파일에 내용을 적는다.

import java.io.FileOutputStream;
import java.io.IOException;

public class Sample {
    public static void main(String[] args) throws IOException {
        FileOutputStream output = new FileOutputStream("c:/out.txt");
        for(int i=1; i<11; i++) {
            String data = i+" 번째 줄입니다.\r\n";
            output.write(data.getBytes());
        }
        output.close();
    }
}

InputStream과 마찬가지로 OutputStream 역시 바이트 단위로 데이터를 처리하는 클래스이다. FileOutputStream은 OutputStream클래스를 상속받아 만든 클래스인데 바이트 단위로 데이터를 처리하게끔 되어 있다.

FileOutputStream에 값을 쓸 때는 byte배열로 써야 하므로 위와같이 String을 byte배열로 바꾸어 주는 getBytes() 메서드를 이용했다. \r\n은 줄바꿈 문자이다.

※ 유닉스인 경우는 \n 만 있으면 된다. 윈도우즈의 경우 \r\n 처럼 \r 문자를 추가해야 노트패드 같은 에디터에서 줄바꿈이 제대로 표시되어 보인다.

FileWriter

문자열을 파일에 쓸 때에는 FileOutputStream이 좀 불편하다. String을 byte배열로 변환해야 하기 때문이다.   FileOutputStream 대신에 FileWriter를 이용하면 byte 배열 대신 문자열을 사용할수 있어 편리하다.

import java.io.FileWriter;
import java.io.IOException;

public class Sample {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("c:/out.txt");
        for(int i=1; i<11; i++) {
            String data = i+" 번째 줄입니다.\r\n";
            fw.write(data);
        }
        fw.close();
    }
}

PrintWriter

하지만 FileWriter를 사용하더라도 \r\n을 문자열 뒤에 덧 붙여야 하는 불편함은 여전히 남아있다. 이런 불편함을 해소하려면 FileWriter대신 PrintWriter를 사용하면 된다. PrintWriter를 이용하면 \r\n을 덧붙이는 대신 println이라는 메써드를 사용할 수 있다.

다음은 PrintWriter를 이용하여 파일을 작성하는 예제이다.

import java.io.IOException;
import java.io.PrintWriter;

public class Sample {
    public static void main(String[] args) throws IOException {
        PrintWriter pw = new PrintWriter("c:/out.txt");
        for(int i=1; i<11; i++) {
            String data = i+" 번째 줄입니다.";
            pw.println(data);
        }
        pw.close();
    }
}

위의 프로그램을 다음의 프로그램과 비교해 본다.

for(int i=1; i<11; i++) {
    String data = i+" 번째 줄입니다.";
    System.out.println(data);
}

두 프로그램의 차이점은 data를 출력시키는 방법이다. 두 번째 방법은 우리가 지금껏 계속 사용해 왔던 콘솔 출력 방법이고 첫 번째 방법은 콘솔대신에 파일로 출력하는 방법이다. 차이점이 금방 눈에 들어 올 것이다. System.out대신에 PrintWriter의 객체를 사용한 차이가 있을 뿐이다.

위의 프로그램을 실행하면 c:/out.txt 파일이 생성된다. 파일에 어떤 내용이 저장되었는지 확인해 본다.

[out.txt의 내용]
1 번째 줄입니다.
2 번째 줄입니다.
3 번째 줄입니다.
4 번째 줄입니다.
5 번째 줄입니다.
6 번째 줄입니다.
7 번째 줄입니다.
8 번째 줄입니다.
9 번째 줄입니다.
10 번째 줄입니다.

두 번째 방법을 사용했을 때 콘솔에 출력될 내용이 파일에 고스란히 들어가 있는 것을 알 수 있다.

파일에 내용 추가하기

프로그램을 만들다 보면 파일에 내용을 쓰고 난 후에 또 새로운 내용을 추가하고 싶을 때가 생긴다. 이럴 경우에는 이미 작성된 파일을 다시 추가모드로 열어서 추가내용을 작성해야 한다.

import java.io.FileWriter;
import java.io.IOException;

public class Sample {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("c:/out.txt");
        for(int i=1; i<11; i++) {
            String data = i+" 번째 줄입니다.\r\n";
            fw.write(data);
        }
        fw.close();

        FileWriter fw2 = new FileWriter("c:/out.txt", true);  // 파일을 추가 모드로 연다.
        for(int i=11; i<21; i++) {
            String data = i+" 번째 줄입니다.\r\n";
            fw2.write(data);
        }
        fw2.close();
    }
}

fw2 객체는 FileWriter("c:/out.txt", true) 와 같이 두번째 파라미터를 추가로 전달하여 생성했다. 두번째 boolean 입력 파라미터는 파일을 추가모드(append)로 열것인지에 대한 구분값이다. 파일을 추가모드로 열면 기존파일의 내용을 덮어쓰지 않고 이후부터 파일이 쓰여진다.

위 예제를 실행하면 out.txt 파일에 내용이 추가되는 것을 확인할 수 있을 것이다.

만약 FileWriter대신 PrintWriter를 이용하고 싶은 경우에는 다음과 같이 변경해야 한다.

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class Sample {
    public static void main(String[] args) throws IOException {
        PrintWriter pw = new PrintWriter("c:/out.txt");
        for(int i=1; i<11; i++) {
            String data = i+" 번째 줄입니다.";
            pw.println(data);
        }
        pw.close();


        PrintWriter pw2 = new PrintWriter(new FileWriter("c:/out.txt", true));
        for(int i=11; i<21; i++) {
            String data = i+" 번째 줄입니다.";
            pw2.println(data);
        }
        pw2.close();
    }
}

PrintWriter를 사용할 경우에는 생성자의 파라미터로 파일명 대신 추가모드로 열린 FileWriter의 객체를 전달해야 한다.

파일 읽기

import java.io.FileInputStream;
import java.io.IOException;

public class Sample {
    public static void main(String[] args) throws IOException {
        byte[] b = new byte[1024];
        FileInputStream input = new FileInputStream("c:/out.txt");
        input.read(b);
        System.out.println(new String(b));  // byte 배열을 문자열로 변경하여 출력
        input.close();
    }
}

파일을 읽기 위해서는 위 예처럼 FileInputStream 클래스를 이용한다. 다만 byte 배열을 이용하여 파일을 읽어야 하기 때문에 읽어야 하는 정확한 길이를 모를 경우에는 좀 불편한 방법이다. 위 예에서는 1024 바이트를 읽도록 코딩했다.

※ 바이트 배열을 문자열로 변경할 때는 new String(바이트배열) 처럼 사용하여 변경한다.

만약 파일을 라인단위로 읽을 수 있다면 훨씬 편리할 것이다. 다음과 같이 예제를 수정한다.

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

public class Sample {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("c:/out.txt"));
        while(true) {
            String line = br.readLine();
            if (line==null) break;  // 더 이상 읽을 라인이 없을 경우 while 문을 빠져나간다.
            System.out.println(line);
        }
        br.close();
    }
}

위 예처럼 FileInputStream 대신 FileReader와 BufferedReader의 조합을 사용하면 라인단위로 파일을 읽을 수 있다. BufferedReader의 readLine 메소드는 더이상 읽을 라인이 없을 경우 null을 리턴한다.

'Language > Java' 카테고리의 다른 글

[Java] 접근제어자 (Access Modifier)  (0) 2022.08.04
[Java] 패키지 (Package)  (0) 2022.08.04
[Java] 콘솔 입출력  (0) 2022.08.04
[Java] 추상클래스  (0) 2022.08.02
[Java] 다형성  (0) 2022.08.02
'Language/Java' 카테고리의 다른 글
  • [Java] 접근제어자 (Access Modifier)
  • [Java] 패키지 (Package)
  • [Java] 콘솔 입출력
  • [Java] 추상클래스
arajo
arajo
  • arajo
    아라 메모장
    arajo
  • 전체
    오늘
    어제
    • 분류 전체보기 (509)
      • Language (298)
        • HTML (55)
        • CSS (11)
        • JavaScript (70)
        • TypeScript (8)
        • Python (33)
        • Java (119)
        • C (0)
        • C# (2)
      • Programming (92)
        • Programming (14)
        • Web (51)
        • Apache (1)
        • MySQL (23)
        • AWS (3)
      • Framework | Library (26)
        • Framework | Library (3)
        • Vue.js (2)
        • React.js (5)
        • React Native (4)
        • Node.js (1)
        • Ajax (1)
        • Bootstrap (8)
        • Spring (1)
        • Flutter (1)
      • etc (2)
      • 휴식 (19)
        • 책 (13)
        • 일기 (5)
        • 게임 일기 (1)
      • A (71)
        • 공부 (18)
        • 기타 (6)
        • 일 (47)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    CSS
    제어문
    변수
    리액트
    타입스크립트
    web
    object
    HTML
    Java
    MySQL
    react
    next.js
    파이썬
    event
    Python
    JavaScript
    자바스크립트
    객체
    array
    TypeScript
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
arajo
[Java] 파일 입출력
상단으로

티스토리툴바