loading
본문 바로가기
BACK-END/JAVA

Stream

by pikiforyou 2020. 9. 16.

 

 

Stream

일련의 연속된 데이터의 흐름

  • 입력스트림 - 데이터 소스에서 프로그램에 흘러 들어오는 스트림
  • 출력스트림 - 프로그램에서 데이터 목적지로 나가는 스트림

자바는 입출력 스트림이 엄격히 구분되어있다

 

Data source : 데이터의 근원(소스) - File, Keyboard, 원격컴퓨터 데이터등 

Data Destination : 데이터가 최종도착하는곳 - File, 모니터, 프린터, 메모리 등

 

데이터소스, 데이터 목적지에 따라서 사용하는게 틀리기때문에 제일 중요하고, 반드시 구분해야한다.

 

 

 

스트림의 특징

  • FIFO 구조 : First in, First out 먼저들어온게 먼저 나간다
  • 단방향 (읽는 스트림, 쓰는 스트림 엄격히 구분) 입출력을 동시에 지원하지 않는다
  • 스트림에 들어간 데이터가 처리되기전에는 스트림을 사용하는 스레드는 블럭킹에 빠진다  ex)키보드 입력시 입력할때까지 블락킹됨 

 

  바이트스트림 / Input, output으로 끝난다 문자스트림(1 or 2 byte) /reader, writer로 끝남
추상클래스 InputStream OutputStream
=PrintStream
Reader Writer
Node Stream FileInputStream
데이터소스가 파일일때
FileOutputStream
데이터목적지가 파일일때
FileReader
데이터소스가 파일
FileWriter
데이터목적지가 파일
Bridge Stream   InputStreamReader OutputStreamWriter
Filter Stream DataInputStream
자료형을 필터링

BufferedInputStream
속도가 조금 빠르다

ObjectInputStream
객체저장,네트워크 전송시
DataOutputStream

BufferedOutputStream

ObjectOutputStream
BufferedReader BufferedWriter

PrintWriter
  입력 출력 입력 출력

Node Stream : 데이터의 소스나 목적지에 직접 연결할 수 있는것

Filter Stream : 직접끼우진못하고 노드중간에 끼워서 필터링을 시킨다

Bridge Stream : 바이트를 -> 문자로 연결하는 스트림. 바이트로 들어온걸 문자로 변경

binary file : jpeg,gif,bmp,avi,mpeg,zip,dll,exe 파일등은 전부 바이너리파일. 바이트기반으로 읽어야한다. 단 txt, hwp등은 문자기반의 FileReader/FileWriter을 사용하는게 좋다

 

 

 

 

 

 


read() / print() / write()

모든 입출력시스템은 사용후 close() 를 이용해 스트림을 닫아야한다. 단, 표준입출력은 닫지않아도 괜찮다.

read(); : 입력스트림으로부터 1바이트씩 읽어서 그 값을 아스키코드값으로 반환. 읽을때는 무조건 read(). 입력이없으면 -1을 반환한다. 

print() : 아스키코드값을 출력하는데 flush할 필요가없다. 출력할때는 무조건 print()

write() : 입력한문자 그대로 출력. 단, 자동 flush가 되지않아서 출력스트림에 있는 값을 데이터목적지로 보내려면 flush() 또는 close()해줘야한다. 단, flush()를 써주자.

 

**readLine() : 필터스트림인 BufferedReader등을 이용했을때 사용할수있는 메소드. 이제 String단위로 읽으며 값이 없으면 null을 반환한다

 

*flush()

write()만 작성하면 출력은되지만, 화면에 나타나지는 않는다. 그래서 flush()나 close()를 해줘야 보이게된다. 단, close()를 하게되면 스트림이 닫히게되므로 그 이후에는 출력되지않는다.

 

** read() 와 read(byte[]) 차이점

1바이트씩 읽어서 읽은 문자를 바이트형배열에 채운다. 입력스트림에 있는 모든문자를 읽은경우 or 바이트형배열이 다 채워진 경우 읽은 바이트 수를 반환한다.

ex) A 입력 -> 반환값 : 3

65(A) 13(\r) 10(\n)  

ex) ABC 입력 -> 반환값 : 4

 65(A) 66(B) 67(C) 13(\r)

 

 

 

 

NodeStream

표준입출력장치 (키보드/모니터)

키보드로 입력받을때는 무조건 : System.in (InputStream)

-키보드에 직접 연결할수있는 바이트 기반의 노드입력스트림

모니터로 출력할때는 무조건 : System.out (PrintStream/OutputStream)

-모니터에 직접 연결할수있는 바이트 기반의 노드출력스트림

표준입출력장치는 close(); 로 닫아주지않아도 된다.

 

 

파일입출력시

바이너리파일등 바이트단위로 전송해야할경우에는 

FileInputStream / FileOutputStream

2바이트이상, 한글등 텍스트파일위주인경우에 더 유리한

FileReader / FileWriter

**바이너리파일 : exe, dll, jpg, avi, mpeg 등의 파일

 

 

 

 

Bridge Stream

바이트로 받은것을 문자(2바이트)로 바꿔주는 스트림

키보드를 통해 입력받고(byte), 파일로 출력하고 싶다면(2byte)

키보드를 통해 입력받았기때문에 바이트로 들어왔다. 문자인 파일로 출력하려면 Bridge stream을 써야하는데, 

들어온기준으로 봐야한다. 즉 바이트로 들어왔기때문에 입력부분에 있는 InputStreamReader 을 써줘야한다.

이후 2바이트로 바뀌었기때문에 목적지로 갈때는 정상적으로 출력한다

데이터소스 : 키보드 -System.in
브릿지스트림 : InputStreamReader
데이터목적지 : 파일 - FileWriter  이렇게 작동한다

 

 

 

 

Filter Stream

필터를 끼워서 좀더 빠른 성능이나, 효율적으로 지나갈수있게 하는것. 유용한 메소드도 사용가능

필터스트림의 생성자인자로 노드스트림을 전달하면 사용완료! 

 

 

BUFFER 계열

BufferedInputStream / BufferdOutputStream

char[] 배열로 계란판을 만들어서 강제적으로 버퍼링효과를 낸것처럼,

Buffer는 내부적으로 계란판을 가지고 있다. (기본 버퍼크기 512바이트)

BufferedInputStream bis = new BufferedInputStream(System.in));
BufferedInputStream bis = new BufferedInputStream(new fileInputStream("src/filename.txt"));

이런식으로 사용해주면된다. 바이트단위 -> 바이트단위로 필터링

 

 

 

BufferedReader / PrintWriter(BufferedWriter)

보통은 PrintWriter로 출력하니까 참고하자.

문자단위로 가져와서 출력 (라인/String)이라 굉장히 편리하다

브릿지스트림을 통해 문자단위로 변환하고 -> 필터스트림(BufferedReader)을 통해 필터링한다

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

이런식으로 사용한다.

가져오는게 바이트단위(노드스트림등)라면 안에서 new를 이용해 넣어주면된다. (위 참조)

 

readLine() : 스트림의 끝/읽을 문자열이없으면 null값 반환. 엔터값을 읽지않고 String단위이기때문에 굉장히 편리하다

 

 

BufferedWriter bw = new BufferedWriter(System.out) 
bw.write("\r\r"+data);
bw.flush();


PrintWriter pw = new PrintWriter(System.out, true);
println(data);

***PrintWriter  vs  BufferedWriter

PrintWriter은 BufferedWriter와 다르게...

객체생성시(true)로 주면 flush()를 호출할필요없다.

출력할때 엔터값을 주지않고 .println(); 으로 출력하면 한줄로 끝난다

따라서 PrintWriter을 쓰면 된다

 

 

 

 


 

DATA 계열

DataInputStream / DataOutputStream

자바의 각 자료형을 인코딩할때 사용하는 필터스트림

데이터소스 : 자바의 각 자료형에 저장된 값 (메모리-변수) //입력스트림 불필요

*DataOutputStream으로 필터링한(암호화된)데이터는 반드시 DataInputStream을 사용해야 제대로 읽어온다. 또한 순서대로 read()해야한다

dos.writeByte(b); 이렇게 저장했다면 
byte b = dis.readByte(); 이렇게 읽어야한다

 

 

OBJECT 계열

ObjectInputStream / ObjectOutputStream

자바클래스는 직렬화가 되야 파일로 저장하거나, 네트워크를 통해 전송할 수 있다.

따라서 저장하고자 하는 객체를 "Serializable" 또는 "Externalizable" 인터페이스를 구현(상속)해서 직렬화를 시켜야한다.

Serializable : 추상메소드가 없어서 보통은 이걸로 상속받는다 (오버라이딩도 안해도되고 말이지)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

댓글