자바(Java) 강의

18. 파일 입출력 (2) - 파일 쓰기

삐멜 2019. 5. 28. 10:21

이번 포스트에서는 자바가 제공하는 몇가지 유틸리티 클래스를 이용해 파일에 데이터를 쓰는 방법을 알아보도록 한다. 이전 포스트에서 File을 이용해 파일 생성하는 법을 했지만, 실제로는 이 유틸리티 클래스를 이용해 파일을 만드는게 보통이다. 이 유틸리티 클래스들은 내부적으로 File클래스를 사용하고 있다. 대신 우리가 디스크에 write하기위한 복잡한 과정을 거치지 않아도 편하게 '쓰기'오퍼레이션이 가능하도록 하는 메서드를 제공한다. 

이전 포스트

목표

  • FileWriter를 이용해 파일 쓰기
  • BufferedWriter를 이용해 파일쓰기
  • PrintWriter를 이용해 파일쓰기
  • FileOutputStream을 이용해 파일쓰기
  • Java 8 try-with-resource
  • Java 8 : java.nio 클래스를 이용해 파일쓰기

프로젝트 구조

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

1 directory, 2 files

FileWriter를 이용해 파일 쓰기

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

public class Main {

public static void main(String[] args) throws IOException {
String fileContent = "파일 쓰기";
String fileName = "my_first_file.txt";
FileWriter writer = new FileWriter(fileName);
writer.write(fileContent);
writer.close();
}
}
FileWriter오브젝트를 생성해 write이라는 메서드로 파일에 데이터를 쓸 수 있다. 만약 파일이 존재하지 않는다면 파일을 생성한 후 쓴다. FileWriter처럼 IO오퍼레이션을 하는 경우에 마지막에 꼭 close메서드를 불러 파일을 닫아줘야 한다.

BufferedWriter를 이용해 파일쓰기

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

public class Main {

public static void main(String[] args) throws IOException {
String fileContent = "파일 쓰기";
String fileName = "my_first_file.txt";
BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
writer.write(fileContent);
writer.close();
}
}

BufferedWriter는 FileWriter를 이용해 쓰기를 한다. 그럼 BufferedWriter와 FileWriter는 뭐가 다를까? FileWriter는 write메서드가 한번 불릴 때 마다 내부적으로 한번의 write 디스크 오퍼레이션(시스템 콜)을 한다. BufferedWriter는 write을 여러번 부르면 내부적으로 Buffer라는 공간에 매개변수로 들어온 데이터를 저장하고있다가, Buffer가 꽉 차면 그때 write 디스크 오퍼레이션(시스템 콜)을 이용해 실제로 디스크에 쓰기를 한다. 디스크 오퍼레이션은 다른 오퍼레이션에 비해 시간이 많이 들기 때문에, write이 불릴때마다 느린 작업을 반복하지말고, 모아놨다가 한방에 써버리는 것이다.

PrintWriter를 이용해 파일쓰기

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

public class Main {

public static void main(String[] args) throws IOException {
String fileContent = "파일 쓰기 PrintWriter";
String fileName = "my_first_file.txt";
PrintWriter writer = new PrintWriter(fileName);
writer.println(fileContent);
writer.close();
}
}
다른 클래스로는 PrintWriter가 있다. PrintWriter도 내부적으로는 위에서 실습한 BufferedWriter를 사용한다. PrintWriter의 가장 큰 장점은 사용하기 쉽다는 것이다. 우리에게 익숙한 System.out.println과 비슷한 형식의 메서드를 제공하기 때문에 사용하기 쉽게 느껴진다.

FileOutputStream을 이용해 파일쓰기

파일에 쓰기를 할때 항상 문자열만 쓰는것은 아니다. 어떤 때는 바이트 형식의 데이터를 써야 할 때도 있다.
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {

public static void main(String[] args) throws IOException {
String fileContent = "파일 쓰기 PrintWriter";
String fileName = "my_first_file.txt";
FileOutputStream outputStream = new FileOutputStream(fileName);
byte[] bytes = fileContent.getBytes();
outputStream.write(bytes);
outputStream.close();
}
}

FileOutputStream을 이용해 byte 배열을 파일에 쓸 수 있다.

Java 8 try-with-resource

매번 .close()를 불러줘야하는게 귀찮고, 잊어버릴수도 있다. 자바 8에서는 이를 해소하기 위해 try-with-resource라는 문법을 제공한다.

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

public class Main {

public static void main(String[] args) throws IOException {
String fileContent = "파일 쓰기";
String fileName = "my_first_file.txt";
try (PrintWriter writer = new PrintWriter(fileName)) {
writer.println(fileContent);
}
}
}

예를들어 PrintWriter를 이용하면 위와 같다. IO관련 클래스들을 try ( IO 오브젝트 생성 ) { IO 작업 } 이렇게 하면  try문이 끝난 후 자바가 알아서 close를 불러준다. 더불어 java 8에서는 nio라는 패키지를 제공해 아래처럼 간단하게 파일 Write을 할 수도 있다.

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

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
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 fileContent = "파일 쓰기 java.nio";
String fileName = "my_first_file.txt";
Path path = Paths.get(fileName);
Files.write(path, fileContent.getBytes());
}
}

이번 포스트에서는 각종 Writer를 이용해 파일 쓰기를 하는 방법을 알아보았다. 다음 포스트에서는 파일 읽기에 대해 알아보도록 한다.

다음 포스트: 18 파일 입출력 (3) 파일 읽기