파일 쓰기
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 |