자바의정석 Chapter15. 입출력
입출력이란
Input 과 Output의 약자로 컴퓨터 내부 또는 외부의 장치와 프로그램간의 데이터를 주고 받는 것을 말합니다.
스트림 (stream)
- 자바에서 입출력을 수행하려면 두 대상을 연결하고 데이터를 전송할 수 있는 연결통로가 필요한데 이를 스트림 이라고 합니다.
- 스트림이란 데이터를 운반하는데 사용되는 연결통로 입니다.
- 스트림은 단방향통신만 가능합니다.
- 스트림은 Queue와 같이 먼저 보낸 데이터를 먼저 받게 됩니다.
- 스트림에는 바이트기반 스트림과 문자기반 스트림이 있습니다.
- 바이트기반 스트림은 InputStream, OutputStream이 있습니다.
- 문자기반 스트림은 Reader, Writer 가 있습니다.
InputStream, OutputStream
InputStream, OutputStream 클래스는 바이트단위로 데이터를 전송하는 바이트 기반 스트림 클래스의 조상 입니다.
InputStream의 메소드는 다음과 같습니다.
메서드명 | 설 명 |
---|---|
int available() | 스트림으로부터 읽어 올 수 있는 데이터의 크기를 반환한다. |
void close() | 스트림을 닫음으로써 사용하고 있던 자원을 반환한다. |
void mark(int readlimit) | 현재위치를 표시해 놓는다. 후에 reset()에 의해서 표시해 놓은 위치로 다시 돌아갈 수 있다. readlimit는 되돌아 갈 수 있는 byte의 수이다. |
boolean markSupported() | mark()와 reset()을 지원하는지를 알려준다. mark()와 reset() 기능을 지원하는 것은 선택적이므로, mark()와 reset()을 사용하기 전에 markSupported()를 호출해서 지원여부를 확인해야 한다 |
abstract int read() | 1byte를 읽어 온다. 더이상 읽어 올 데이터가 없으면 -1을 반환한다. |
int read(byte[] b) | 배열 b의 크기만큼 읽어서 배열을 채우고 읽어 온 데이터의 수를 반환한다. |
int read(byte[] b, int off, int len) | 최대 len개의 byte를 읽어서, 배열 b의 지정된 위치(off)부터 저장한다. 실제로 읽어 올 수 있는 데이터가 len개 보다 적을 수 있다. |
void reset() | 스트림에서의 위치를 마지막으로 mark()이 호출되었던 위치로 되돌린다. |
long skip(long n) | 스트림에서 주어진 길이(n)만큼을 건너뛴다. |
OutputStream의 메소드는 다음과 같습니다.
메서드명 | 설 명 |
---|---|
void close() | 입력소스를 닫음으로써 사용하고 있떤 자원을 반환한다. |
void flush() | 스트림의 버퍼에 있는 모든 내용을 출력소스에 쓴다. |
abstract void write(int b) | 주어진 값을 출력소스에 쓴다. |
void write(byte[] b) | 주어진 배열 b에 저장된 모든 내용을 출력소스에 쓴다. |
void write(byte[] b, int off, int len | 주어진 배열 b에 저장된 내용 중에서 off번째부터 len개 만큼을 읽어서 출력소스에 쓴다. |
ByteArrayInputStream, ByteArrayOutputStream
메모리, 즉 바이트배열에 데이터를 입출력 하는데 사용되는 스트림입니다. 주로 다른 곳에 입출력 하기 전에 데이터를 임시로 바이트배열에 담아서 변환 등의 작업을 하는데 사용 됩니다.
[예제]
byte[] inSrc = {0,1,2,3,4,5,6,7,8,9}
byte[] outSrc = null;
byte[] temp = new byte[4];
ByteArrayInputStream input = null;
ByteArrayOutputStream output = null;
try {
while(input.available() > 0) {
int len = input.read(temp); // 읽어 온 데이터의 개수를 반환한다.
output.write(temp, 0, len); // 읽어 온 만큼만 write한다.
}
} catch(IOException e) {}
outSrc = output.toByteArray();
System.out.println("Input Source : " + Arrays.toString(inSrc));
System.out.println("Temp : " + Arrays.toString(temp));
System.out.println("Output Source : " + Arrays.toString(outSrc));
[실행 결과]
Input Source : [1, 2, 3, 4, 5, 6, 7, 8, 9]
Temp : [8,9,6,7]
Output Source : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
FileInputStream, FileOutputStream
파일에 입출력을 하기 위한 스트림입니다.
생성자 | 설 명 |
---|---|
FileInputStream(String name) | 지정된 파일이름(name)을 가진 실제 파일과 연결된 FileInputStream을 생성한다. |
FileInputStream(File file) | 파일의 이름이 String이 아닌 File인스턴스로 지정해주어야 하는 점을 제외하고 FileInputStream(String name)와 같다. |
FileInputStream(FileDescriptor fdObj) | 파일 디스크립터로 FileInputStream을 생성한다. |
FileInputStream(String name) | 지정된 파일이름(name)을 가진 실제 파일과의 연결된 FileOutputStream을 생성한다. |
FileOutputStream(String name, boolean append) | 지정된 파일이름(name)을 가진 실제 파일과 연결된 FileOutputStream을 생성한다. 두번째 인자인 append를 true로 하면, 출력 시 기존의 파일내용의 마지막에 덧붙인다. false이면 기존의 파일내용을 덮어쓰게 된다. |
FileOutputStream(File file) | 파일의 이름을 String이 아닌 File인스턴스로 지정해주어야 하는 점을 제외하고 FileOutputStream(String name)과 같다. |
FileOutputStream(File file, boolean append) | 파일의 이름을 String이 아닌 File인스턴스로 지정해주어야 하는 점을 제외하고 FileOutputStream(String name, boolean append)과 같다. |
FileOutputStream(FileDescriptorfdObj) | 파일 디스크립터(fdObj)로 FileOutputStream을 생성한다. |
FilterInputStream, FilterOutputStream
- Input, Output Stream의 자손이면서 모든 보조스트림의 조상입니다.
- 생성자 FilterInputStream(InputStream in)은 접근제어자가 protected이기 때문에 인스턴스를 생성해서 사용 할 수 없고 상속을 통해서 오버라이딩 되어야 합니다.
BufferedInputStream, BufferedOutputStream
- 스트림의 입출력 효율을 높이기 위해 버퍼를 사용하는 보조 스트림입니다.
- 한 바이트씩 입출력 하는 것보다는 버퍼(바이트배열)를 이용해서 한번에 여러 바이트를 입출력 하는 것이 빠르기 때문에 대부분의 입출력 작업에 사용 됩니다.
- BufferedInputStream은 입력소스로 부터 버퍼 크기만큼의 데이터를 읽어와 자신의 내부 버퍼에 저장 후 처리 하기 때문에 빠르게 처리가 가능 합니다.
- BufferedOutputStream 역시 버퍼를 이용해서 출력소스와 작업을 하는데 프로그램에서 write메서드를 이용한 출력이 버퍼에 저장됩니다.
- BufferedOutputStream 는 버퍼가 가득 찼을 때만 출력소스에 출력하기 때문에 마지막 출력시 버퍼가 가득 차지 못할 경우 출력되지 않기 때문에 flush() 또는 close() 처리를 통해 출력 시켜줍니다.
- 보조스트림을 close 처리 시 기반 스트림은 자동 close 처리 됩니다.
[예제]
String fileName = "C:/AksStudio/lib.txt";
File file = new File(fileName);
if(file.exists()) { // 파일이 존재 한다면
BufferedInputStream bis = null;
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
byte[] buffer = new byte[fis.available()];
bis.read(buffer);
System.out.println(new String(buffer));
while ((bis.read(buffer)) != -1) {
//sb.append(new String(buffer, 0, i));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}else {
System.out.println("[Error] Not found file");
}
DataInputStream, DataOutputStream
생략
Reader, Writer
- 문자기반 스트림의 조상클래스로 char 배열 단위를 사용한다는것 이외에는 모두 바이트 기반 스트림과 동일 합니다.
- 문자기반 스트림은 단순히 2byte로 스트림만을 처리하는 것은 아니며 여러종류의 인코딩과 유니코드간의 변환을 자동으로 처리해줍니다.
- Reader는 특정 인코딩을 읽어서 유니코드로 변환하고 Writer는 유니코드를 특정 인코딩으로 변환하여 저장 합니다.
Reader의 메소드는 다음과 같습니다.
메서드명 | 설 명 |
---|---|
abstract void close() | 입력스트림을 닫음으로써 사용하고 있던 자원을 반환한다. |
void mark(int readlimit) | 현재위치를 표시해놓는다. 후에 reset()에 의해서 표시해 놓은 위치로 다시 돌아갈 수 있다. |
boolean markSupperted() | mark()와 reset()을 지원하는지를 알려준다. |
int read() | 입력소스로부터 하나의 문자를 읽어 온다. char의 범위인 0~65535범위의 정수를 반환하며, 입력스트림의 마지막 데이터에 도달하면 -1을 반환한다. |
int read(char[] c) | 입력소스로부터 매개변수로 주어진 배열 c의 크기만큼 읽어서 배열 c에 저장한다. 읽어 온 데이터의 개수 또는 -1을 반환한다. |
abstract int read(char[] c, int off, int len | 입력소스로부터 최대 len개의 문자를 읽어서 배열 c의 지정된 위치(off)부터 읽은 만큼 저장한다. 읽어 온 데이터의 개수 또는 -1을 반환한다. |
int read(CharBuffer target) | 입력소스로부터 읽어서 문자버퍼(target)에 저장한다. |
boolean ready() | 입력소스로부터 데이터를 읽을 준비가 되어있는지 알려준다. |
void reset() | 입력소스에서의 위치를 마지막으로 ark()가 호출되었던 위치로 되돌린다. |
long skip(long n) | 현재 위치에서 주어진 문자 수(n)만큼을 건더뛴다. |
Writer의 메소드는 다음과 같습니다.
메서드명 | 설 명 |
---|---|
Writer append(char c) | 지정된 문자를 출력소스에 출력한다. |
Writer append(CharSequence c) | 지정된 문자열(CharSequence)을 출력소스에 출력한다. |
Writer append(CharSequence c, int start, int end) | 지정된 문자열(CharSequence)의 일부를 출력소스에 출력한다. |
abstract void close() | 출력스트림을 닫음으로써 사용하고 있던 자원을 반환한다. |
abstract void flush() | 스트림의 버퍼에 있는 모든 내용을 출력소스에 쓴다. |
void write(int b) | 주어진 값을 출력소스에 쓴다. |
void write(char[] c) | 주어진 배열 c에 저장된 모든 내용을 출력소스에 쓴다. |
abstract void write(char[] c, int off, int len) | 주어진 배열 c에 저장된 내용 중에서 off번째부터 len길이만큼만 출력소스에 쓴다. |
void write(String str) | 주어진 문자열(str)을 출력소스에 쓴다. |
void write(String str, int off, int len) | 주어진 문자열(str)의 일부를 출력소스에 쓴다. |
FileReader, FileWriter
파일로부터 텍스트데이터를 읽고, 파일에 쓰는데 사용합니다.
[예제]
try {
String fileName = "test.txt";
FileReader fr = new FileReader(fileName);
int data = 0;
while((data=fr.read())!=-1){
System.out.print((char)data);
}
fr.close();
} catch (IOException e){
e.printStackTrace();
}
PipeReader, PipedWriter
- 쓰레드 간에 데이터를 주고받을 때 사용 합니다.
- 다른 스트림과는 달리 입력과 출력스트림을 하나의 스트림으로 연결해서 데이터를 주고 받습니다.
- 스트림 생성 후 어느 한쪽에서 connect()를 호출하면 연결 되며 어느 한쪽에서 close()를 호출하면 연결이 끊어집니다.
BufferedReader, BufferedWriter
버퍼를 이용해서 입출력의 효율을 높일 수 있또록 해주는 역할을 합니다.
[예제]
try {
FileReader fr = new FileReader("test.txt");
BufferedReader br = new BufferedReader(fr);
String line = "";
for(int i = 1 ; (line = br.readLine()) != null; i++){
if(line.indexOf(";") != -1)
System.out.println(i+":"+line);
}
br.close();
} catch(IOException e) {}
InputStreamReader,OutputStreamWriter
- 바이트기반 스트림을 문자기반 스트림으로 연결시켜주는 역할을 합니다.
- 바이트기반 스트림의 데이터를 지정된 인코딩 문자데이터로 변환 하는 작업을 수행합니다.
InputStreamReader 메소드
생성자 / 메서드 | 설 명 |
---|---|
InputStreamReader(InputStream in) | OS에서 사용하는 기본 인코딩의 문자로 변환하는 InputStreamReader를 생성한다. |
InputStreamReader(InputStream in, String encoding) | 지정된 인코딩을 사용하는 InputStreamReader를 생성한다. |
String getEncoding() | InputStreamReader의 인코딩을 알려 준다. |
OutputStreamWriter 메소드
생성자 / 메서드 | 설 명 |
---|---|
OutputStreamWriter(OutputStream in) | OS에서 사용하는 기본 인코딩의 문자로 변환하는 OutputStreamReader를 생성한다. |
OutputStreamWriter(OutputStream in, String encoding) | 지정된 인코딩을 사용하는 OutputStreamWriter를 생성한다. |
String getEncoding() | OutputStreamWriter의 인코딩을 알려 준다. |
Reference
자바의 정석
댓글남기기