보조 스트림, 문자 변환, 성능 향상, 기본 타입 입출력, 개행 출력
이전에 배웠던 데이터 입출력 -> 기본 스트림 4개 : Input/OutputStream, Reader,Writer 직접 사용
여기서 배울 데이터 입출력 : 데이터를 변환해서 입출력 하고싶을 때, 데이터 출력 형식을 지정하고 싶을 때, 입출력 성능 향상을 원할 때! 기본 스트림에 보조 스트림을 연결해 사용한다.
보조 스트림 : 다른 스트림과 연결이 되어서 여러 편리 기능을 제공하는 스트림
ㄴ문자 변환, 입출력, 성능 향상, 기본 타입 출력 등 기능 제공
ㄴ자체적으로 입출력 수행은 안된다. => 입출력 소스와 바로 연결되는 Input/OutputStream, Reader,Writer 등에 연결해야 한다.
ㄴ이때 프로그램은 입출력스트림으로부터 직접 데이터를 읽고 보내지 않는다! 보조 스트림의 기능을 이용해서 데이터를 읽고 보낸다
ㄴ그럼 보조스트림을 어떻게 연결할까
보조스트림 변수 = new 보조스트림(연결스트림)
보조 스트림 생성시 자신이 연결될 스트림을 생성자의 매개값으로 넣는다.
ㅇㅖ )
InputStream과 문자변환보조스트림 InputStreamReader을 연결해보자
InputStream is = ...;
InputStreamReader reader = new InputStreamReader(is);
++보조 스트림을 연속적으로 연결할 수 있다
ㄴ보조 스트림 생성자 매개값에 또 다른 보조 스트림을 넣을 수 있다.
ㅇㅖ )
문자변환 보조스트림 InputStreamReader과 성능향상 보조스트림 BufferedReader을 연결하기
InputStream is = ...;
InputStreamReader reader = new InputStreamReader(is);
BufferedReader br = new BufferedReader(reader);
이렇게 보조 스트림을 연결연결 한다~.~
이제 보조 스트림에는 어떤 것들이 있는지 공부 스타트~! (헉 모두의마블 하고싶다)
<<학습예정>>
문자변환 보조스트림
OuputStreamWriter
InputStreamReader
성능향상 보조스트림
BufferedOutputStream
BufferedWriter
BufferedInputStream
BufferedReader
기본타입 입출력 보조스트림
DataInputStream
DataOutputStream
프린터 보조스트림
PrintStream - 바이트기반 출력스트림과 연결
PrintWriter - 문자기반 출력스트림과 연결
객체 입출력 보조스트림
ObjectOutputStream
ObjectInputStream
문자 변환 보조스트림
!! 문자 입출력은 Writer, Reader가 편리하다 !!
=>이 때문에 입출력 데이터가 문자라면 Reader와 Writer로 변환해 사용해도 된다
=>문자 변환 보조스트림을 공부하자
(소스 스트림이 바이트기반 스트림(InputStream, OutputStream, FileInputStream, FileOutputStream)
이면 이 문자변환 보조스트림을 통해 Reader와 Writer로 변환해 사용할 수 있다는 말)
OutputSreamWriter
Writer writer = new OutputStreamWriter(바이트기반 출력스트림);
예) 파일출력을 위한 바이트기반FileOutputStream을 Writer타입으로 변환 가능하다.
FileOutputStream fos = new FileOutputStream("C:/Temp/test1.txt); //어어 txt다
Writer writer = new OutputStreamWriter(fos);
이렇게 바이트기반스트림을 Writer생성자의 매개값으로 집어넣으면 된다.
Writer 변수 = new OutputStreamWriter(바이트기반 출력스트림)
InputStreamReader
Reader reader = new InputStreamReader(바이트기반 입력스트림);
예) 파일입력을 위한 바이트기반 FileInputStream을 Reader타입으로 변환 가능하다.
FileInputStream fis = new FileInputStream("C:/Temp/test1.txt"); /txt네
Reader reader = new InputStreamReader(fis);
○예제 : 파일로 문자를 저장하고 저장된문자를 다시 읽는다.
소스 스트림은 바이트기반 FileOutputStream, FileInputStream이지만 이 스트림들을 직접 이용하지 않고, 보조 스트림을 이용하여 각각 Writer과 Reader로 변환해 입출력 할 거다.
성능향상 보조스트림
프로그램 실행 성능 : 가장 늦는 입출력 장치를 따른다.
ㄴ하드디스크 입출력 늦으면 프로그램실행성능은 하드디스크 처리속도에 맞춰진다.
ㄴ네트워크환경이 느리면 데이터 전송이 늦으므로 프로그램 실행성능이 늦어진다.
실행 성능 향상 시키기 : 프로그램이 입출력 소스와 직접 작업하지 않도록 한다.
ㄴ중간에 메모리 버퍼(buffer)와 작업하게 한다!
ㄴex) 프로그램이 하드디스크에 직접 데이터를 보내지 않고, 메모리 버퍼에 데이터를 고속 전송하여 보내기
=>쓰기속도 향상
ㄴ버퍼 : 데이터를 바로 하드디스크로 보내지 않고, 쌓아놨다가 꽉 차면 한꺼번에 데이터를 하드디스크로 보낸다.
=>출력 횟수 감소
+출력스트림은 내부에 작은 버퍼를 기본적으로 갖고 있긴 한데, 이걸로 불충분하여 보조스트림을 이용한다.
ㄴ메모리 버퍼를 추가 제공 => 프로그램 실행성능 향상시키는 보조스트림을 공부하자.
바이트 기반 스트림에 연결 : BufferedInputSream, BufferedOutputStream
문자 기반 스트림에 연결 : BufferedReader, BufferedWriter
각 기반 스트림에 연결되어 버퍼를 제공해준다.
BufferedOutputStream, BufferedWriter
=>프로그램에서 전송한 데이터를 내부 버퍼에 쌓아 뒀다가 꽉 차면 => 버퍼의 모든 데이터를 한꺼번에 목적지로 보낸다. (데이터를 메모리 버퍼로 고속전송하기 때문에 출력 성능 향상)
<<사용 - 추가적인 내부 버퍼 만들기 by 보조스트림>>
BufferedOutputStream bos = new BufferedOutputStream(바이트기반 출력스트림);
BufferedWriter bw = new BufferedWriter(문자기반 출력스트림);
BufferedInputStream, BufferedReader
=>입력소스로부터 자신의 내부버퍼 크기만큼 데이터를 읽고 버퍼에 저장해둔다 => 그러면 프로그램은 버퍼에 있는 데이터를 읽는다 (=>읽기 성능 향상!)
ㄴ프로그램이 외부 입력 소스로부터 직접 읽는게 아니라는 거!
ㄴ입력 소스는 미리 버퍼에다가 데이터를 차곡차곡 채워 두는 거다. 그리고 프로그램이 '버퍼에있는 데이터'를 고속으로 읽어 읽기 성능을 향상시키는 것이다.
<<사용 - 추가적인 내부 버퍼 만들기 by 보조스트림>>
BufferedInputStream bis = new BufferedInputStream(바이트기반 입력스트림);
BufferedReader br = new BufferedReader(문자기반 입력스트림);
○예제 : 실행 성능 차이 (성능향상 보조스트림 이용 여부에 따라서)
ㄴ파일 복사 실행 성능 차이!
얼마나 실행 성능이 좋아지는지 보자.
++그런데.. 클래스 파일이 있는 장소에 저 getResource() 메소드 안에 있는 파일을 안만들어주면 NullPointerException 뜨는데.. 왜지 ㅠㅠ 책에는 아무런 말이 없는데..
이 문제 예전에 class클래스의 getResource() 메소드 공부할 때 겪은 문제다 ㅠㅠ
조금 이따 찾아보자..
복습 : Class 클래스
메소드
ㅇClass객체 얻기 : getClass(), forName()
ㅇ클래스 경로를 활용해서 리소스 절대경로 얻기 : getResource()
https://splendidlolli.tistory.com/107
기본타입 입출력 보조스트림
DataInputStream과 DataOutputStream 보조 스트림 연결 =>
기본타입인 boolean, char, short, int, long, float, double 입출력 가능
이것두 보조 스트림이니까
생성할 때 : 연결할 바이트입출력 스트림을 생성자의 매개값에 넣는다
DataInputStream dis = new DataInputStream(바이트기반 입력스트림);
DataOutputStream dos = new DataOutputStream(바이트기반 출력스트림);
<<이 기본타입 입출력 보조스트림 2개가 제공하는 메소드>>
DataInputStream | DataOutputStream | ||
boolean | readBoolean() | void | writeBoolean(boolean v) |
byte | readByte() | void | writeByte(int v) |
char | readChar() | void | writeChar(int v) |
double | readDouble() | void | writeDouble(double v) |
float | readFloat() | void | writeFloat(float v) |
int | readInt() | void | writeInt(int v) |
long | readLong() | void | writeLong(long v) |
short | readShort() | void | writeShort(int v) |
String | readUTF() | void | writeUTF(String str) |
ㄴ데이터 크기가 모두 다르다 : 출력한 거 읽을때 출력할때와 순서 동일하게 읽어야 함
예) 출력해온 곳에서 순서를 int boolean double로 했으면 읽을 때 순서도 동일해야 한다는 것.
○예제 : 이름, 성적, 순위 순으로 파일에 출력을 하고 다시 이름, 성적, 순위 순으로 파일로부터 입력받자
프린터 보조스트림
PrintStream, PrintWriter =>print(), println() 메소드를 가지고 있다.
!!헉
지금까지 사용해왔던 System.out => 콘솔 출력 스트림
이게 바로 PrintStream타입이라고 한다. => 그래서 print(), println()메소드를 사용할 수 있었던 것..
뜨든!!
(이 스트림에 있는 메소드 println()과 print()는 출력할 데이터타입에 따라 오버로딩 되어있다.)
PrintStream : 바이트 기반 출력스트림과 연결된다.
PrintWriter : 문자 기반 출력스트림과 연결된다.
=>생성하기 : 보조스트림이니까.. 연결할 출력 스트림을 생성자 매개값에 넣으면서 보조스트림을 생성한다.
PrintStream ps = new PrintStream(바이트기반 출력스트림);
PrintWriter pw = new PrrintWriter(문자기반 출력스트림);
○예제 : FileOutputStream에 보조스트림으로 PrintStream연결해서 print(), println()메소드 사용하기
객체 입출력 보조스트림
ObjectOutputStream, ObjectInputStream이라는 보조스트림을 연결하면
메모리에 생성된 객체를 파일or네트워크로 출력할 수 있다!!
우와 ㅠㅠ
*직렬화 : 객체를 바이트 배열로 만드는것
*역직렬화 : 바이트배열을 다시 객체로 복원하는 것
ObjectOutputStream : 객체를 직렬화한다.
ObjectInputStream : 객체로 역직렬화한다.
음 그러면 객체를 바이트배열로 만들어서 출력한 것이 어떤 파일이나 네트워크로 들어가는구나
그리고 그걸 프로그램에서 다시 입력받을 때에는 다시 바이트배열을 객체로 복원해서 입력을 받군..!!
컴터니까 바이트 배열로 맨드러서 받는곤가..
**그런데 자바가 모든 객체를 직렬화하는건 아니다..!
자바는 그럼 어떤 객체를 직렬화할 수 있는건가~!
=>java.io.Serializable 인터페이스를 구현한 객체만 직렬화한다!
ㄴ이 인터페이스에는 메소드 선언 없다.
만약 내가 객체를 파일로 저장 / 네트워크로 전송할 목적이라면
클래스를 선언할 때 implements Serializable을 추가해주면 된다.
JVM에게 '직렬화해도 좋다~!'고 승인하는 역할이라고 하네!!
생성=>마찬가지로.. 보조스트림을 생성할 때는 연결할 바이트기반 스트림을 생성자의 매개값으로 받는다.
ObjectInputStream ois = new ObjectInputStream(바이트기반 입력스트림);
ObjectOutputStream oos = new ObjectOutputStream(바이트기반 출력스트림);
<<메소드>>
ㅇObjectOutputStream
ㄴwriteObject() : 객체를 직렬화해서 출력스트림으로 보낸다.
oos.writeObject(객체);
ㅇObjectInputStream
ㄴreadObject() : 입력스트림에서 읽은 바이트배열을 역직렬화 =>객체로 다시 복원해 리턴한다.
ㄴ이때, 리턴타입은 Object다..!!
=>헉 너무 그르차나 그러니까 원래 타입으로 강제타입변환 해야함
객체타입 변수 = (객체타입) ois.readObject();
○예제 :
List컬렉션을 => 파일로 저장하고 읽는다.
List컬렉션의 구현클래스로 ArrayList 사용 => 그리고 ArrayList는 Serializable인터페이스를 구현하고 있다.
(즉, '파일에 저장', '네트워크에 전송'... 이 가능하다)
※ArrayList에 저장되는 객체 또한!!!!!!!! Serializable 인터페이스를 구현하는 객체여야 한다.
(그래서 아래 예제의 Board객체도 Serializable 인터페이스를 구현하게 작성해야 함)
복습 복습 복습
'JAVA' 카테고리의 다른 글
[혼자 공부하는 자바] 8/16 14-3 [입출력 관련 API] (0) | 2020.08.16 |
---|---|
[6주차] 기본미션 + 선택미션 [혼공단] [혼공자] (0) | 2020.08.16 |
[혼자 공부하는 자바] 8/14 14-1 [입출력 스트림] [문자 기반 스트림] [문자 입출력 스트림] [Writer] [Reader] (0) | 2020.08.14 |
[혼자 공부하는 자바] 8/13 14-1 [입출력 스트림] [바이트 기반 스트림] [바이트 입출력 스트림] [InputStream] [OutputStream] (0) | 2020.08.13 |
[혼자 공부하는 자바] 8/13 13-2 [컬렉션프레임워크] [LIFO(후입선출)/Stack클래스] [FIFO(선입선출)/Queue인터페이스] (0) | 2020.08.13 |