입출력 FilterOutputStream.java
입출력
>> "자바의 입출력은 네트워크 환경을 위한것이다" 라고 말할 정도로 자바에서 입출력은 네트워크 환경을 구현하는데 꼭 필요한 부분
>> 자바에서 네트워크를 다룬다는 것은 데이터와 정보를 읽고 쓰는 입출력에 관련된 환경이나 장치를 가지고 프로그래밍하는 것
>> 자바의 입출력 관련 클래스들은 모두 java.io 패키지에 들어있다.
1. 스트림
>> 자바에서는 어떤 대상 또는 목적지(파일, 네트워크, 프린터 따위)에 데이터를 읽고 쓰기 위해 직접 접근하여
데이터를 읽고 쓰는 것이 아니라 입출력을 담당하는 객체를 위임하는 방식.
이때 입출력을 담당하는 객체를 '스트림 객체'
1) 스트림이란?
- 데이터의 입출력을 위해 스트림 방식 사용
* 스트림(stream)
- 방향이 있는 하나의 흐름을 의미
- 보통 8비트(1바이트)로 이루어진 데이터의 흐름
- 스트림은 순차적인 흐름이므로 내부적으로 먼저 들어온것이 먼저 나가는 선입선출의 구조
- 자바의 모든 입출력은 스트림 구조
|
2. 스트림의 종류
>> 스트림은 기본 입출력 스트림과 문자 관련 스트림으로 나눔
1) 스트림과 최상위 클래스
기본 입출력 스트림 (바이트 스트림) |
문자 관련 스트림 (문자 스트림) |
입력 스트림 (InputStream 클래스) |
문자 입력 스트림 (ReaderStream 클래스) |
출력 스트림 (OutputStream 클래스) |
문자 출력 스트림 (WriterStream 클래스) |
2) 기본 입출력 스트림
- 기본 입출력 스트림은 1바이트(8비트) 또는 정수와 같이 간단한 자료를 읽고 쓰기 위한 스트림
- 자바에서 스트림 구조의 클래스는 모두 java.io 패키지에 들어있음.
(1) 입력 스트림
- 프로그램 안으로 데이터를 읽어 들이는 스트림
- InputStream 클래스는 추상 바이트 입력 스트림 클래스로서 입력장소를 기억하고 있다가 이 장치에서 바이트를 읽고 제어하는 메소드 제공
- 이 클래스는 추상 클래스이기 때문에 인스턴스를 생성할 수가 없으나 입력을 위한 메소드가 정의
|
* InputStream의 서브 클래스 기능
클래스 |
기능 설명 |
ByteArrayInputStream |
바이트 배열로부터 데이터를 읽어 들일 때 사용 |
FileInputStream |
파일을 읽어 들일 때 사용 |
FilterInputStream |
줄의 수 모니터링, 버퍼링, 원시데이터의 입력등의 기능 |
BufferedInputStream |
버퍼링을 입력에 사용 |
CheckedInputStream |
데이터의 신뢰성을 향상시키기 위하여 읽혀지는 데이터 체크섬 사용 |
DataInputStream |
기본 데이터 형식으로 데이터를 읽어 들일 때 사용 |
LineNumberInputStream |
입력 라인의 수를 세는데 사용 |
PushbackInputStream |
바이트를 읽고 여러 개의 바이트로 구성된 병합 형태를 형성, |
ObjectInputStream |
프로그램에서 주로 활용, 객체 형태의 데이터를 읽을 때 사용 |
PipeInputStream |
PipedOutputStream으로부터 읽기를 지원하는 기능 |
SequenceInputStream |
단을 스트림으로 FileInputStream을 연결할 때 사용 |
StringBufferInputStream |
문자열을 버퍼링을 사용하여 입출력에 사용 |
* InPutStream 클래스가 제공하는 대표적인 메소드
메소드 |
설명 |
abstract int read() |
입력 스트림으로부터 1바이트를 일고, 읽은 문자를 int형으로 반환 스트림의 끝일 경우에는 -1을 반환, 읽어 들인 데이터를 문자로 |
int read(byte[] b) |
입력 스트림으로부터 바이트 배열의 b의 크기만큼 읽어온다 |
int read(byte[] b, |
입력 스트림으로부터 시작위치인 off부터 len의 길이만큼 읽어서 |
int read(char[] cbuf) |
입력 스트림으로부터 char 배열 cbuf의 크기만큼 읽어온다 |
int available() |
현재의 입력 스트림으로부터 지연되지 않고 읽어 들일 수 있는 |
void close() |
해당 입력 스트림을 닫는다 |
long skip(long n) |
입력 수트림으로부터 읽어 들인 데이터를 n 바이트 크기만큼 |
void mark(int readlimit) |
입력 스트림의 현재 위치를 표시 |
boolean markSupported() |
입력 스트림이 표시(mark) 작업을 지원하면 true, |
void reset() |
mark() 메소드의 마지막 호출이 지정한 위치로 입력 스트림의 |
(2) 출력 스트림
- 프로그램에서 출력장치나 외부 기억장치로 데이터를 내보낼때 사용하는 스트림
- 출력 목적지를 기억하고 있다가 이 장치에 바이트를 출력,제어하는 메소드 제공
|
* OutputStream의 서브 클래스 기능
클래스 |
기능 설명 |
ByteArrayOutputStream |
바이트 배열로부터 데이터를 출력할 때 사용 |
FileOutputStream |
파일에 데이터를 출력할 때 사용 |
FilterOutputStream |
다음 5개의 서브 클래스 제공 |
BufferOutputStream |
버퍼링을 사용하여 출력에 사용 |
CheckedOutputStream |
데이터의 신뢰성을 향상시키기 위하여 출력되는 데이터 체크섬 사용 |
DataOutputStream |
기본 데이터 형식으로 데이터를 출력할 때 사용 |
InflaterOutputStream |
압축 라이브러리(ZLIB)를 사용해서 압축해서 출력할 때 사용 |
PrintStream |
스트림을 화면등에 출력할 때 사용. System.out은 리턴 타입으로 PrintStream 을 갖음 |
ObjectOutputStream |
프로그램에서 주로 활용하며, 객체 형태의 데이터를 출력할 때 사용 |
PipedOutputStream |
스트림을 PipedOutputStream으로 출력할 때 사용 |
* OutputStream 클래스가 제공하는 대표적인 메소드
메소드 |
설명 |
abstract void write(int b) |
출력 스트림에 1바이트를 출력 int형의 정수를 인수로 받지만 byte로 자동 형변환된 후에 출력 |
void write(byte[] b) |
출력 스트림에 바이트 배열에서 b의 크기만큼 출력 |
void write(byte[] b, int off, int len) |
시작위치인 off부터 len의 길이만큼, 출력 스트림에 바이트 배열에서 b의 크기만큼 출력 |
void close() |
출력 스트림을 닫는다 |
void flush() |
버퍼에 남아있는 데이터를 출력 스트림에 출력 보통 출력 스트림에 들어있는 데이터는 어느 정도 내부 버퍼에 데이터가 쌓일 때까지 기다렸다가 출력하는 것을 flush()메소드를 써서 바로 출력 |
3) 문자 관련 입출력 스트림
- 문자 스트림을 따로 구분해서 사용하는 이유는 바이트 단위로 문자를 읽어 들여 국제 문자 표준코드인 유니코드로 변환시켜 주기 위함
- 16비트 문자나 문자열을 읽고 출력하는 스트림
>> 스트림은 바이트 단위로 데이터를 읽고 쓰지만, 리더/라이터를 연결하면 2바이트 문자단위나 문자열의 데이터를 읽고 씀
(1) Reader 클래스
- 영어 외의 문자인 한국어, 일본어 등의 문자를 처리하는 입력 스트림
- 이 클래스는 문자 입력 스트림 클래스의 최상위 클래스로서 입력장소를 기억하고 있다가 이 장치에서 유니코드 문자를 읽어들이고 제어하는 메소드 제공
- 입력 되는 소스 데이터가 바이트 스트림이면 바이트 데이터를 유니코드 문자 데이터로 변환하여 유니코드 문자를 입력 받을 수 있음
|
* Reader의 서브 클래스의 기능
클래스 |
서브 클래스 |
기능 설명 |
BufferedReader |
LineNumberReader |
BufferedReader는 문자 스트림에서 버퍼링을 사용하여 효율적인 입력을 위해 사용. LineNumberReader는 입력 라인의 수를 세는데 사용 |
CharArrayReader |
|
문자들의 배열을 문자 스트림으로 읽는다 |
FilterReader |
PushbackReader |
PushbackReader는 문자들을 문자 스트림으로 되돌려 놓는 기능 제공 |
InputStreamReader |
FileReader |
InputStreamReader는 InputStream을 Reader로 변환 시킴. FileReader는 파일을 문자로 읽는다 |
PipedReader |
|
파이프화된 문자 스트림으로 읽는다. |
StringReader |
|
String 형식으로 문자를 읽어드린다. |
* Reader 클래스가 제공하는 대표적인 메소드
메소드 |
설명 |
int read() |
하나의 문자를 읽어서 int 형으로 반환 |
int read(char[] cbuf) |
입력 스트림으로부터 char 배열 cbuf의 크기만큼 읽어온다. |
abstract int read(char[] cbuf, int off, int len) |
입력 스트림으로부터 시작위치인 off부터 len의 길이만큼 읽어서 char 배열 cbuf의 크기만큼 읽어온다 |
int read(CharBuffer target) |
입력 스트림으로부터 문자 버퍼인 target으로 문자들을 읽어온다 |
boolean ready() |
입력 스트림으로부터 읽을 준비가 되었으면 true, 그렇지 않으면 false를 반환 |
abstract void close() |
입력 스트림을 닫는다 |
void mark(int readlimit) |
입력 스트림의 현재 위치를 표시, 후에 reset()메소드를 사용하여 이 위치를 찾을 수 있도록 함 |
boolean markSupported() |
입력 스트림이 표시(mark) 작업을 지원하면 true, 지원하지 않으면 false를 반환 |
void reset() |
mark()메소드의 마지막 호출이 지정한 위치로 입력 스트림의 위치를 다시 위치 |
long skip(long n) |
입력 스트림으로부터 n 크기만큼의 문자를 읽어서 건너뛴다. |
(2) writer 클래스
- 문자 단위로 출력을 수행
- 이 클래스는 문자 출력 스트림 클래스의 최상위 클래스로서 출력할 목적지를 기억하고 있다가 이 장치에 유니코드 문자를 출력하고 제어하는 메소드 제공
- 목적지가 바이트 스트림이면 유니코드 문자 데이터를 바이트 데이터로 변환하여 유니코드 문자를 출력할 수 있게 함.
|
* Writer의 서브 클래스 기능
클래스 |
서브 클래스 |
기능 설명 |
BufferedWriter |
|
문자 스트림에서 버퍼링을 사용하여 효율적인 출력 |
CharArrayWriter |
|
문자 스트림의 내용을 문자 배열에 출력 |
FilterWriter |
|
필터링하여 출력 |
OutputStreamWriter |
FileWriter |
OutputStreamWriter는 OutputStream을 Writer로 변환시킴. FileWriter는 문자로 읽어서 파일에 출력 |
PipedWriter |
|
파이프화된 문자 스트림에 출력 |
StringWriter |
|
String 형식으로 문자를 출력 |
PrintWriter |
|
화면등에 출력 |
* Writer 클래스가 제공하는 대표적인 메소드
메소드 |
설명 |
void write(String str) |
문자열 str을 출력 스트림에 출력 |
void write(String str, int off, int len) |
시작위치인 off부터 len의 길이만큼, |
abstract void close() |
출력 스트림을 닫는다 |
abstract void flush() |
출력 스트림을 비운다. |
# 예제
package stream; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; public class IStreamReader { static String fname; public static void main(String[] args) { int idata = -1; //InputStream 객체에 Reader 연결. 바이트 스트림을 문자 스트림으로 변환 Reader isr = new InputStreamReader(System.in); System.out.println("키보드에서 문자입력[마지막에 엔터]" ); System.out.println("--------------------------------"); try{ //입력중에 발생할지 모를 예외처리 while(true){ idata = isr.read(); //InputStreamReader 객체가 1문자 읽음 if(idata == -1) break; System.out.print((char)idata); //문자로 형변환 } } catch(IOException e){ System.out.println(e.toString()); } } } |
> 결과
|
3. 파일
>> File 클래스와 RandomAccessFile 클래스는 파일이나 폴더를 다른 클래스와 독립적으로 관리 할 수 있게 하는 인터페이스 제공
1) File 클래스
- 작성된 자바 프로그램이 어떠한 운영체제에서도 프로그램 수정없이 실행되게 제공하는 것
- File클래스는 파일을 제어하도록 제공되는데, 파일의 삭제, 파일 이름의 변경, 파일의 존재 확인 등과 같은 제어를 한다
- File 클래스를 생성하기 위해서는 파일 이름을 인수로 주기만 하면 됨.
* File 클래스의 생성자
생성자 설명 File(String pathname) Pathname 디렉토리로 File 객체 생성 File(String pathname, String filename) Pathname 디렉토리에 존재하는 File(File dir, String filename) 디렉토리에 dir에 존재하는
filename 이름의 File 객체 생성
filename 이름의 File 객체 생성
> pathname은 파일이 있는 디렉토리 경로 이름
> filename은 파일의 이름
> dir은 디렉토리 경로명을 가지고 있는 File객체
예) File file1 = new File("c:\java");
File file2 = new File("c:\java", "batch.bat");
File file3 = new File(file1, "batch.bat");
2) RandomAccessFile 클래스
- 파일의 입출력을 순차적으로 하지 않고 그 위치를 사용자 마음대로 바꾸어 입출력을 수행
- 다른 클래스들은 입력과 출력을 서로 다른 클래스에서 수행하지만, RandomAccessFile 클래스는 입력과 출력을 동시에 수행
- RandomAccessFile 클래스는 일반적인 스트림 관련 클래스들과 달리 InputStream과 OutputStream을 상속 받지 않으므로
FilterStream과 같은 다른 크래스들을 사용하는데 제한
- 그대신 DataInput과 DataOutput 인터페이스를 구현하여 자바의 기본 데이터 타입을 읽고 쓸수 있게하는 메소드 제공
* RandomAccessFile의 생성자
생성자 |
설명 |
RandomAccessFile(String name, String mode) |
파일이름이 name이고 mode 형식인 파일에 |
RandomAccessFile(File file, String mode) |
Mode 형식이고 file 객체가 가리키는 파일에 |
>> RandomAccessFile 클래스는 파일 이름이나 File 객체를 매개변수로 넘겨주는 두가지의 생성자를 사용
>> 파일 접근 모드 - 읽기전용 : "r"
- 읽고쓰기 가능 : "rw"
예) RandomAccessFile ifile = new RandomAccessFile("inputFile.dat","rw");
>> RandomAccessFile 클래스는 파일 포인터를 원하는 위치로 옮기거나 원하는 위치를 찾는 따위의 일을 하는 메소드 제공
3) 파일 입출력하기
- File 클래스에는 파일에 직접 입출력할 수 있는 메소드가 없다
- 2바이트 단위의 기본 입출력 방식을 처리하는 FileInputStream, FileOutputStream클래스와
유니코드 문자열 방식을 처리하는 FileReader, FileWriter 클래스가 파일의 입출력을 담당
- 자바에서 파일 입출력은 애플리케이션 프로그램에서만 가능
애플릿은 웹상에서 사용되기 때문에 보안상 파일 입출력을 살 수도 없고 로칼 장치에 접근할 수 없다