![paxd](https://t1.daumcdn.net/tistory_admin/static/manage/images/r3/default_L.png)
스트림
자바에서 입출력 스트림은 응용프로그램과 입출력 장치를 연결하는 소프트웨어 모듈로서, 입출력 장치와 응용프로그램 사이에서 데이터가 순서대로 전송되도록 한다.
스트림의 특징
스트림은 입력 스트림과, 출력 스트림 2가지 이며, 스트림 입출력의 기본 단위는 바이트이고, 선입 선출 방식으로 들어오는 순서대로 전달한다.
스트림 연결
스트림은 서로 연결하여 사용할 수 있다.
import java.io.IOException;
import java.io.InputStreamReader;
public class Stream {
public static void main(String[] args) throws IOException {
InputStreamReader rd = new InputStreamReader(System.in);
while (true) {
int c = rd.read();
if (c == -1)
break;
System.out.println((char) c);
}
}
}
문자 입력 스트림에 표준입력을 연결하여 다음과 같이 Hello란 글자를 시스템에 출력이 가능하다.
사진 1 스트림 연결
바이트 스트림
바이트 스트림은 바이트를 단위로 다루는 스트림이다. 스트림에 들어오고 나가는 정보를 단순 바이너리로 바꾸기 때문에, 문자든 이미지 바이트든 상관없이 흘려 보낸다.
바이트 스트림 클래스
Java.io 패키지에 포함되고, 공통적으로 Stream을 붙인다.
문자 스트림
문자 스트림은 문자만 다룰 수 있기 때문에, 문자가 아닌 데이터가 문자 출력 스트림에 출력되면 출력이 보이지 않거나 엉뚱한 기호가 출력되며, 문자가 아닌 정보가 문자 입력 스트림에 입력되면 응용프로그램에게 엉뚱한 문자가 전달되는 오류를 발생한다.
문자 스트림 클래스
Java.io 패키지에 포함되어 있고, 문자 스트림을 다루는 클래스는 Reader/Writer를 붙여 구분한다.
필터 입출력 스트림
텍스트 파일 읽기
문자 스트림은 문자를 단위로 다루는 스트림으로, 문자가 아닌 바이너리 값들은 제대로 처리하지 못한다.
문자 스트림 파일 입출력 클래스인 FileReader/FileWriter를 이용하여 텍스트 파일을 읽고 쓸 수 있다.
1. 파일 입력 스트림 생성(파일 열기)
FileReader rd = new FileReader("c:\\window\\system.ini");
2. 파일 읽기
int c;
while ((c = rd.read()) != -1) {
System.out.print((char) c);
}
파일 입출력 시 read함수는 파일의 끝 EOF를 만나면 -1 를 리턴 한다. 따라서 while문은 -1이 아닌 것을 모두 처리하면 된다.
3. 스트림 닫기
스트림이 더 이상 필요 없게 되면 닫아야 한다. Cloase() 메소드를 호출하여 스트림을 닫는다.
rd.close();
파일 경로명 문자열
자바는 '\'를 특수 문자로 다루기 때문에, 문자열에 '\' 문자를 사용하고자 하면 '\\'와 같이 백슬래시를 두 번 사용하도록 하고 있다.
read()의 리턴 타입이 int인 이유
Read의 리턴 타입을 char로 처리하게 되면 파일의 끝인 -1을 리턴할 때 0xFF 즉 -1을 리턴 하게 되어 EOF 처리를 할 수 없게 된다. 하지만 int형으로 EOF를 처리하게 되면 0x000000FF로 리턴을 하며, int형에서의 -1은 0xFFFFFFFF로 리턴 값이 구분이 되는 것을 알 수 있다. 따라서 int형으로 받아 강제 타입 변환을 이용하여 char형으로 치환하여 받아들인다.
FileReader의 생성자 및 주요 메소드
사진 2 FileReader 생성자
사진 3 FileReader 메소드
파일 입출력과 예외 처리
파일 입출력 실행 중 예외가 발생할 수 있다.
- 파일의 경로명이 틀리거나, 어떤 상황으로 파일을 열 수 없는 경우 -> FileNotFoundException 예외 발생
- 파일 읽기, 쓰기, 닫기를 하는 동안 디스크 오작동이나 파일이 깨진 경우 등으로 인해 입출력 오류 발생 -> IOException 예외 발생
그러므로 다음과 같이 입출력 코드 전체를 감싸는 try-catch 블록이 필요하다. 또한 FileNotFoundException 예외는 IOException에서 상속받으므로 생략이 가능하다.
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Stream {
public static void main(String[] args){
try{
FileReader rd = new FileReader("c:\\windows\\system.ini");
int c;
while ((c = rd.read()) != -1) {
System.out.print((char) c);
}
rd.close();
} catch(FileNotFoundException e){
System.out.println("파일을 열 수 없음");
} catch(IOException e){
System.out.println("입출력 오류");
}
}
}
텍스트 파일 쓰기
FileWriter를 이용하여 파일 출력 스트림을 만들고, 텍스트 파일에 저장하는 방법을 알아보자.
1. 파일 스트림 생성
FileWriter fout = new FileWriter("d:\\test.txt");
파일이 없는 경우 빈 파일을 생성하며, 이미 파일이 있는 경우 파일 내용을 지우고 처음부터 쓰기가 진행된다.
2. 파일 쓰기
다음과 같이 파일에 한 문자만을 쓰는 것도 가능하고,
fout.write('A');
다음과 같이 한 번에 블록단위로 쓸 수도 있다.
char[] buf = new char[1024];
fout.write(buf, 0, buf.length);
3. 스트림 닫기
텍스트 파일을 다 작성 하였으면 스트림을 닫는다.
fout.close();
FileWrite 생성자와 주요 메소드
사진 4 FileWrite 생성자
사진 5 FileWrite 주요 메소드
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
public class Stream {
public static void main(String[] args) {
InputStreamReader in = new InputStreamReader(System.in);
FileWriter fout = null;
int c;
try {
fout = new FileWriter("d:\\test2.txt");
while ((c = in.read()) != -1) {
fout.write(c);
}
in.close();
fout.close();
} catch (IOException e) {
System.out.println("입출력 오류");
}
}
}
바이너리 파일 쓰기
바이너리 파일 입출력을 위한 대표적 스트림 클래스는 FileInputSteam/FileOutputStream이다.
프로그램 내의 변수나 배열에 들어 있는 바이너리 값을 그대로 파일에 저장할 필요가 있다. 예를 들면 이미지 파일 같은 파일들은 바이너리로 구성되어 있다.
바이너리 파일을 쓰는 법은 다음과 같다.
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamEx {
public static void main(String[] args) {
byte b[] = { 7, 51, 3, 4, -1, 24 };
try {
FileOutputStream fout = new FileOutputStream("d:\\test.out"); //파일 출력 스트림 생성
for (int i = 0; i < b.length; i++) // 파일 쓰기
fout.write(b[i]);
fout.close(); //파일 스트림 닫기
} catch (IOException e) {
}
System.out.println("d:\\test.out을 저장하였습니다. ");
}
}
FileOutputStream 생성자와 주요 메소드
사진 6 FileOutputStream 생성자
사진 7 FileOutputStream 주요 메소드
바이너리 파일 읽기
바이트 스트림으로 파일을 읽는 스트림 클래스는 FileInputStream 클래스이다.
import java.io.FileInputStream;
import java.io.IOException;
public class FileOutputStreamEx {
public static void main(String[] args) {
byte b[] = new byte[6];
try {
FileInputStream fin = new FileInputStream("d:\\test.out"); // 입력 파일 스트림 열기
int n = 0, c; //파일 읽기
while ((c = fin.read()) != -1) { //파일 읽기
b[n] = (byte) c;
n++;
}
System.out.println("d:\\test.out에서 읽은 배열을 출력합니다."); // 읽은 파일 콘솔에 출력하기
;
for (int i = 0; i < b.length; i++) // 읽은 파일 콘솔에 출력하기
System.out.print(b[i] + " ");
System.out.println();
fin.close(); // 파일 입력 스트림 닫기
} catch (IOException e) { // 예회처리
}
}
}
FileInputStream 생성자와 주요 메소드
사진 8 FileInputStream 생성자
사진 9 FileInputStream 주요 메소드
파일처리 클래스
File 클래스란?
File 클래스는 파일이나 디렉터리에 대해 다음과 같은 기능을 제공한다.
- 경로명, 파일 크기, 파일 타입, 파일 수정 날짜 등 파일에 관한 속성 정보 제공
- 파일 삭제, 디렉터리 생성, 파일 이름 변경, 디렉터리 내의 파일 리스트 제공 등 파일 관리작업을 지원
File 객체 생성
File 객체는 생성자를 이용하여 생성한다.
사진 10 File 클래스 생성자
File f = new File("d:\\test.txt");
혹은 디렉터리와 파일 이름을 따로 지정해 줄 수 있다.
File f = new File("d:\\tmp", "test.txt");
File 객체는 다음과 같이 스트림 생성 시 생성자에 파일 경로명을 전달하기 위해 이용된다.
FileReader fr = new FileReader(f);
File 클래스 활용
File 클래스를 이용하면, 파일 크기와 타입을 알아내고, 파일 삭제, 이름 변경, 디렉터리 생성, 디렉터리의 파일 리스트 얻기 등 다양한 파일 관리 작업을 수행할 수 있다.
다음은 File 클래스의 주요 메소드이다.
사진 11 File 클래스 주요 메소드
다음은 몇 가지의 파일 메소드 이용 사례를 알아본다.
1. 파일 크기, length()
long size = f.length();
System.out.print(f.length());
2. 파일 경로명, getName(), getPath(), getParent()
getName()은 파일명, getPath()는 완전경로명, getParent()는 부모 디렉터리를 문자열로 리턴하여 준다.
System.out.println(f.getName());
System.out.println(f.getPath());
System.out.println(f.getParent());
사진 12 파일 경로명 메소드
3. 파일 타입 판별, isFile()과 isDirectory()
isFile(), IsDirectory()는 경로명이 파일인지 디렉터리인지에 따라 true, false를 리턴 한다.
if(f.isFile())
System.out.println(f.getPath() + "는 파일입니다.");
else if(f.isDirectory())
System.out.println(f.getPath() + "는 디렉터리입니다.");
사진 13 파일 타입 판별
4. 디렉터리에 있는 파일 리스트 얻기, listFiles()
import java.io.File;
import java.io.FileNotFoundException;
public class FileClassEx {
public static void main(String[] args) throws FileNotFoundException {
File f = new File("d:\\");
File[] subfiles = f.listFiles();
for (int i = 0; i < subfiles.length; i++) {
System.out.print(subfiles[i].getName());
System.out.println("\t 파일 크기: " + subfiles[i].length());
}
;
}
}
사진 14 디렉터리에 있는 파일 리스트 얻기
텍스트 파일 복사
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileClassEx {
public static void main(String[] args) throws FileNotFoundException {
File src = new File("c:\\windows\\system.ini");
File dest = new File("d:\\system.txt");
int c;
try {
FileReader fr = new FileReader(src);
FileWriter fw = new FileWriter(dest);
while ((c = fr.read()) != -1) {
fw.write((char) c);
}
fr.close();
fw.close();
System.out.println(src.getPath() + "를" + dest.getPath()
+ "에 복사하였습니다.");
} catch (IOException e) {
System.out.println("파일 복사 오류");
}
}
}
블록 단위 바이너리 파일 고속 복사
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileClassEx {
public static void main(String[] args) throws FileNotFoundException {
File src = new File("C:\\Intel\\0.png");
File dest = new File("d:\\picture.png");
try {
FileInputStream fi = new FileInputStream(src);
FileOutputStream fo = new FileOutputStream(dest);
byte buf[] = new byte[1024 * 10];
while (true) {
int n = fi.read(buf);
fo.write(buf, 0, n);
if (n < buf.length)
break;
}
fi.close();
fo.close();
System.out.println(src.getPath() + "를" + dest.getPath()
+ "에 복사하였습니다.");
} catch (IOException e) {
System.out.println("파일 복사 오류");
}
}
}