19일차 2023-04-03
1. IO (input, output)
<짧게 메모>
InputStream: read() 메서드 사용
outputStream: write() 메서드 사용
데이터 소스 :데이터 뽑아오는 곳
데이터 목적지: 데이터를 최종적으로 보내는 곳
소스와 Stream사이를 노드라 부름 (4개)
그래서 inputStream, outputStream을 노드 스트림이라 부름
필터스트림을 거쳐 데이터 변형: 데이터 소스나 데이터 목적지에 직접 끼울 수 없다
노드스트림에 끼워서 사용된다.
스트림 생성: (의미) 빨대를 꽂았다 (노드스트림이 생겼다)
입력, 출력이 끝나면 close()한다(걷어드린다)
자바는 Stream을 정확히 나눠져 있다 (inputStream, outputStream으로 나눠져 있다, 다른 언어에서는 한 stream으로 쓰기도 한다) :단방향구조
스트림에 들어간 데이터가 처리되기 전에는 스트림을 사용하는 스레드는 블로킹에 빠진다(이 코드가 진행되기 전까지 아래 코드로 넘어가지 않는 걸 뜻함)
바이트 스트림: 바이트 단위로 흘려보냄
문자 스트림: 문자 단위로 흘려보냄
추상 클래스: 바이트스트림
노드 스트림: 데이터 소스나 목적지에 직접 연결할 수 있는 스트림.
데이터 소스와 목적지를 먼저 파악. 그래야 내가 어떤 스트림을 써야 하는지 판단가능
필터 스트림 : 앞에 다른 게 용도가 다르다는 것(뒤에 inputStream, outputStream)
노드 스트림: 키보드로 입력(무조건 Byte기반 스트림)
모니터로 출력(무조건 byte기반 스트림)
키보드 모니터를 표준 입출력 장치라 한다
단계 : 스트림 생성 => read()/write() => close()
스트림에 A에 있는데 flush() 플러싱해줘야 모니터에 들어감
close()하면 자동 플러싱: 다 모니터로 보냄
close() 뒤는 출력 안됨
영문, 숫자는 1바이트, 한글은 2바이트
필터를 끼우면 속도가 빨라짐, 필터의 메서드를 활용할 수 있어진다
</짧게 메모>
1-1) Stream
/*
[표준 입출력 장치:]
표준 입력장치:키보드
표준 출력장치:모니터
키보드(데이타소스)로부터 데이터를 읽어서
모니터(데이터 목적지)에 출력하자
노드 스트림: 데이터 소스나 목적지에 직접 연결할 수 있는 스트림.
키보드에 직접 연결할 수 있는 바이트 기반의
노드 스트림(입력 스트림):System.in
모니터에 직접 연결할 수 있는 바이트 기반으
노드스트림(출력 스트림):System.out
*/
STDNodeInOut.java
package io24.node;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
/*
[표준 입출력 장치:]
표준 입력장치:키보드
표준 출력장치:모니터
키보드(데이타소스)로부터 데이타를 읽어서
모니터(데이타 목적지)에 출력하자
노드 스트림: 데이타 소스나 목적지에 직접 연결 할 수 있는 스트림.
키보드에 직접 연결할 수 있는 바이트 기반의
노드 스트림(입력 스트림):System.in
모니터에 직접 연결할 수 있는 바이트 기반으
노드스트림(출력 스트림):System.out
*/
public class STDNodeInOut {
public static void main(String[] args) throws IOException {
//1] 바이트 기반의 입력용 노드 스트림 생성(키보드와 직접 연결 가능한 노드 스트림)
InputStream is= System.in;
//2] 바이트 기반의 출력용 노드 스트림 생성(모니터와 직접 연결 가능한 노드 스트림)
PrintStream out=System.out;
//3]is(입력스트림)로 읽고 out(출력스트림)로 출력
//3-1]is로 키보드로부터 입력 받기
/*
* int read():입력스트림으로 부터 1바이트씩 읽어서
* 그 값을 아스키 코드값으로 반환
*/
//int ascii=is.read();//int ascii=System.in.read();와 같다.
//3-2]out로 모니터에 출력
//4-1]print()계열 메소드로 출력:아스키 코드값을 출력.
//print계열은 flush할 필요 없음.
//out.println("입력한 문자:"+ascii);//System.out.println("입력한 문자:"+ascii);와 같다
//4-2]write()계열 메소드로 출력
// 입력한 문자 그대로 출력
//write계열 메소드는 자동 flush가 안된다.
//즉 출력 스트림에 있는 값을 데이타 목적지로 보내려면
//flush()해주거나 close()를 해줘야 한다.
//out.write(ascii);
//out.flush();
//out.close();//스트림 닫기
//출력 스트림을 닫으면 이후 출력 불가
//out.println("프로그램 끝");
//※모든 입출력 스트림은 사용후 스트림을 닫아야한다.
// 단 ,표준 입출력 스트림은 닫지 않아도 무방.
//ABC라고 입력후 엔터치자
/*
out.println(ascii);
out.println((char)is.read());
out.println((char)is.read());
out.println(is.read());//13
out.println(is.read());//10*/
//[사용자가 입력한 문자 그대로 출력하기 즉 ABC를 그대로 모니터(콘솔)에 출력]
/*
ctrl+z(이클립스용 콘솔)를 입력할때
(read()는 -1반환)
엔터값:\r\n ->\r:13 ,\n:10(아스키 코드값)
*/
int ascii;
/*
while((ascii=is.read()) != -1 ) {
//방법1]write계열 사용
//out.write(ascii);
//out.flush();
//방법2]print계열 사용(한글은 깨짐)
//out.print((char)ascii);
}*/
/* 사용자가 입력한 문자열을 변수에 그대로 저장 */
// 즉 read()메소드로 Scanner클래스의 nextLine()메소드 기능 구현하기
/*
out.println("문자열을 입력하세요?");
StringBuilder buf = new StringBuilder();
while((ascii=is.read()) !=13) {
buf.append((char)ascii);
}
out.println("입력한 문자열:"+buf);*/
int totalByte=0,repeatCount=0;
StringBuilder buf = new StringBuilder();
//ABCDE 12345엔터
//필터 효과 적용전]
//총 바이트 수:11,반복 회수:11,입력 문자열:ABCDE 12345
/*
while((ascii=is.read()) !=13) {
totalByte++;
repeatCount++;
buf.append((char)ascii);
}*/
//필터 효과 적용]
/*
read(): 1바이트씩 읽어서 "읽은 문자"의 "아스키 코드값" 반환
read(byte[]):1바이트씩 읽어서 읽은 문자를 바이트형 배열에 채운다.
입력스트림에 있는 모든 문자를 읽은 경우
혹은 바이트형 배열이 다 채워진 경우
"읽은 바이트 수" 반환
*/
byte[] b = new byte[10];
boolean isEnter= false;//ctrl+z안 누르고 바로 엔터시 빠져 나올때
//is.read(b)를 호출하여 입력 스트림으로부터 최대 10바이트를 읽어옵니다. 읽어온 바이트 데이터는 b 배열에 저장됩니다.
while((ascii= is.read(b)) != -1) {
//System.out.println(ascii);//반환 값인 ascii에는 실제로 읽어온 바이트 수가 저장됩니다.
totalByte+=ascii;
repeatCount++;
//읽은 바이트수(ascii)만큼 반복하면서
for(int i=0; i < ascii;i++) {
if(b[i] !=13 && b[i] !=10) buf.append((char)b[i]);
else if(b[i]==13) {//ctrl+z안누르고 바로 엔터시 빠져 나올때
isEnter=true;
break;
}
}
if(isEnter) break;
}
//총 바이트수에서 2(엔터값)를 빼준다
out.println(String.format("총 바이트 수:%s,반복 횟수:%s,입력 문자열:%s",totalByte-2,repeatCount,buf));
}/////////////main
}////////////////class
KeyboardToMonitorFile//Keyboardtxt
/*
키보드로 데이터를 입력받아 입력 받은 내용을
파일과 모니터로 출력
데이타 소스:키보드
바이트 노드 스트림:System.in
데이터 목적지:
파일
바이트 노드 스트림:FileOutputStream
모니터
바이트 노드 스트림:System.out
*/
디렉토리 표기법
package io24.node;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
public class KeyboardToMonitorFile {
public static void main(String[] args) throws IOException {
//1]데이타 입력용 바이트 기반의 노드 스트림 생성
InputStream is = System.in;
//2-1]파일 출력용
//window식 디렉토리 표기법
//FileOutputStream fos = new FileOutputStream("D:\\CCH\\Workspace\\Java\\Basic\\JavaSEProj\\src\\io24\\node\\Keyboard.txt");
//유니스/리눅스식 디렉토리 표기법
//FileOutputStream fos = new FileOutputStream("D:/CCH/Workspace/Java/Basic/JavaSEProj/src/io24/node/Keyboard.txt");
//파일 경로:src부터 시작]
FileOutputStream fos = new FileOutputStream("src/io24/node/Keyboard.txt");
//2-2]모니터 출력용
PrintStream out = System.out;
//3]is로 읽고 fos와 ps으로 출력
int ascii;
while((ascii = is.read()) != -1) {//ctrl +z
//파일로 출력]
fos.write(ascii);
fos.flush();
//모니터로 출력]
out.write(ascii);
out.flush();
}
//4]스트림 닫기
fos.close();
}
}
FileInputStreamToMonitorFIle.java

package io24.node;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileInputStreamToMonitorFile {
public static void main(String[] args) throws IOException {
//1]입력 스트림 생성
FileInputStream fis = new FileInputStream("src/io24/node/Keyboard.txt");
//2]출력 스트림 생성
//모니터용]
OutputStream out=System.out;
//파일용]
FileOutputStream fos = new FileOutputStream("src/io24/node/KeyboardCopy.txt");
//3]fis로 읽고 fos와 out로 출력
int data;
while((data = fis.read()) !=-1) {//파일의 끝에 도달하면 -1반환
//모니터로 출력]
out.write(data);
out.flush();
//파일로 출력]
fos.write(data);
fos.flush();
}
//4]스트림 닫기
fis.close();
fos.close();
}//////////////main
}////////////////class
ImageToImage.java

package io24.node;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ImageToImage {
public static void main(String[] args) {
//1]입출력 스트림 객체 선언
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//2]입력 스트림 생성
fis = new FileInputStream("src/io24/node/이질화.bmp");
//3]출력 스트림 생성
fos = new FileOutputStream("src/io24/node/이질화Copy.bmp");
//4]fis로 읽고 fos로 출력
int data;
long startTime = System.currentTimeMillis();
/*
//필터효과 적용전
while((data= fis.read()) !=-1) {
fos.write(data);
fos.flush();
}*/
//필터효과 적용
byte[] b = new byte[1024];
while((data= fis.read(b)) !=-1) {
//write(배열명,0,읽은 바이트 수):읽은 바이트 수만큼 출력
fos.write(b, 0, data);
fos.flush();
}
long endTime = System.currentTimeMillis();
System.out.println("이미지 복사 소요시간:"+(endTime-startTime)/1000.0+"초");
}
catch(FileNotFoundException e) {
System.out.println("파일이 존재하지 않아요");
}
catch(IOException e) {
System.out.println("파일 읽기시 오류");
}
finally {
try {
if(fis !=null) fis.close();
if(fos !=null) fos.close();
}
catch(IOException e) {e.printStackTrace();}
}
}////////////////main
}//////////////////class
InOutExample.java
package io24.node;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class InOutExample {
public static void main(String[] args) throws IOException {
//문]STDNodeInOut.java 파일의 내용을 읽어서
// 모니터와 파일로 출력하여라.
// 파일로 출력시 파일명은 STDNodeInOut.txt로 하자.
FileInputStream fis = new FileInputStream("src/io24/node/STDNodeInOut.java");
FileOutputStream fos = new FileOutputStream("src/io24/node/STDNodeInOut.txt");
int data;
while((data=fis.read()) !=-1) {
fos.write(data);
fos.flush();
System.out.write(data);
System.out.flush();
}
fis.close();
fos.close();
}//////main
}/////////class
KeyboardToFileWriter.java
package io24.node;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class KeyboardToFileWriter {
public static void main(String[] args) throws IOException {
//1]바이트 기반 입력 스트림 생성
//InputStream is = System.in;
//2]브릿지 스트림을 이용해서 바이트 기반 입력을 문자 기반으로 변환
InputStreamReader isr = new InputStreamReader(System.in);
//3]문자 기반의 출력 스트림생성
FileWriter fw = new FileWriter("src/io24/node/KeyboardWriter.txt");
//is로 읽고 fw로 출력-한글이 깨진다]
int data;
/*
while((data=is.read()) !=-1) {//ctrl+z
fw.write(data);
fw.flush();
}*/
//4]isr로 읽어서 fw로 출력
///read()는 바이트 단위가 아니라 문자 단위로 읽는다.
//고로 총 바이트수를 카운트로 알아내기 힘들다.
int totalChar=0;//읽은 문자 수
int repeatCount=0;
/*
//필터 효과 적용전]
while((data=isr.read()) !=-1) {//ctrl+z
totalChar++;
repeatCount++;
fw.write(data);
fw.flush();
}*/
//필터 효과 적용]
char[] cbuf = new char[10];
//read(char[] cbuf)는 읽은 문자 수 반환
//실제 데이타는 cbuf에 저장됨.
//read(byte[])와 차이점은 read(char[])는 배열이 다 안채워져도 엔터를 만나면 읽은 문자 수 반환된다
while((data=isr.read(cbuf)) !=-1) {//ctrl+z
totalChar+=data;
repeatCount++;
//write(char[],0,읽은 문자수)
fw.write(cbuf,0,data);
fw.flush();
}
System.out.println("총 입력 문자수:"+totalChar+",반복횟수:"+repeatCount);
//스트림 닫기
fw.close();
}///////////////main
}//////////////////class
FileReaderToMonitor.java
package io24.node;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
public class FileRedearToMonitor {
public static void main(String[] args) throws IOException {
//1]입력 스트림 생성
FileReader fr = new FileReader("src/io24/node/KeyboardWriter.txt");
//2]출력 스트림 생성
//PrintStream out = System.out;
//3]브릿지 스트림으로 1바이트 씩 출력 스트림으로 내보내는
// 데이타를 문자단위로 변환
OutputStreamWriter osw = new OutputStreamWriter(System.out);
int data;
/*
//fr로 읽고 out으로 출력-한글깨짐
while((data=fr.read()) !=-1) {
out.write(data);
out.flush();
}*/
//4]fr로 읽고 osw로 출력
while((data=fr.read()) !=-1) {
osw.write(data);
osw.flush();
}
//5]스트림 닫기
fr.close();
}/////////////////main
}///////////////////class
FIleReaderToFileWriter.java
package io24.node;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileReaderToFileWriter {
public static void main(String[] args) throws IOException {
//문]FileInputStreamToMonitorFile.java를 문자단위로 읽어서
// FileInputStreamToMonitorFile.txt 파일로 문자단위로 저장하여라.
//1]입력 스트림 생성
FileReader fr = new FileReader("src/io24/node/FileInputStreamToMonitorFile.java");
//2]출력 스트림 생성
FileWriter fw = new FileWriter("src/io24/node/FileInputStreamToMonitorFile.txt");
//3]fr로 읽고 fw로 출력
int data;
while((data=fr.read()) !=-1) {
fw.write(data);
fw.flush();
}
//4] 스트림 닫기
fw.close();
fr.close();
}/////////////main
}////////////////class
2. Buffer필터 스트림
BufferedInOutKeyboardToFile.java
package io24.filter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedInOutKeyboardToFile {
public static void main(String[] args) throws IOException {
//1]필터를 끼운 입력 스트림 생성
BufferedInputStream bis = new BufferedInputStream(System.in);
//2]필터를 끼운 출력 스트림 생성
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("src/io24/filter/KeyboardBuffered.txt"));
//3]bis로 읽고 bos로 출력
int data;
while((data=bis.read()) !=-1) {
bos.write(data);
bos.flush();
}
//4]스트림 닫기
bos.close();
}/////////////main
}/////////////class
BufferedInOutKeyboardToMonitor.java
package io24.filter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
public class BufferedInOutKeyboardToMonitor {
public static void main(String[] args) throws IOException {
/*
노드 스트림과 필터 스트림 연결방법]
필터 스트림 생성자의 인자로 노드스트림을 전달하면 된다.
*/
//1]필터를 끼운 입력 스트림 생성
BufferedInputStream bis = new BufferedInputStream(System.in);
//2]필터를 끼운 출력 스트림 생성
BufferedOutputStream bos = new BufferedOutputStream(System.out);
//3]bis로 읽고 bos로 출력
int data;
while((data=bis.read()) !=-1) {
bos.write(data);
bos.flush();
}
}
}
BufferedInOutFileToMonitor.java
package io24.filter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class BufferedInOutFileToMonitor {
public static void main(String[] args) throws IOException {
//1]필터를 끼운 입력 스트림 생성
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("src/io24/filter/KeyboardBuffered.txt"));
//2]필터를 끼운 출력 스트림 생성
BufferedOutputStream bos = new BufferedOutputStream(System.out);
//3]bis로 읽고 bos로 출력
int data;
while((data= bis.read()) !=-1) {
bos.write(data);
bos.flush();
}
//4]스트림 닫기
bis.close();
}
}
BufferedInOutFileToFile.java
package io24.filter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedInOutFileToFile {
public static void main(String[] args) throws IOException {
//1]필터를 끼운 입력 스트림 생성
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("src/io24/node/FileRedearToMonitor.java"));
//2]필터를 끼운 출력 스트림 생성
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("src/io24/filter/FileRedearToMonitor.txt"));
//3]bis로 읽고 bos로 출력
int data;
while((data= bis.read()) !=-1) {
bos.write(data);
bos.flush();
}
//4]스트림 닫기
bis.close();
bos.close();
}
}
BufferedRWKeyboardToMonitor.java
package io24.filter;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class BufferedRWKeyboardToMonitor {
public static void main(String[] args) throws IOException {
//1]필터를 끼운 입력 스트림 생성
BufferedReader br =
new BufferedReader(
new InputStreamReader(System.in));
//2]필터를 끼운 출력 스트림 생성
BufferedWriter bw =
new BufferedWriter(
new OutputStreamWriter(System.out));
//3]br로 읽고 bw로 출력
/*
BufferedReader의 readLine()메소드: 스트림의 끝에 도달하면 null을 반환 하거나
읽은 문자열이 없는 경우 null반환
엔터값을 읽지 않는다*/
String data;
/*
while((data = br.readLine()) != null) {
//방법1]읽어온 데이타 뒤에 엔터값 추가
//bw.write(data+"\r\n");
//bw.flush();
//방법2]줄바꿈 기능을 하는 메소드 호출:newLine()
bw.write(data);
bw.newLine();
bw.flush();
}*/
/*
[PrintWriter-출력용 필터 스트림]
PrintWriter 객체 생성시 생성자의 두번째 인자로
true를 주면 autoflush지원. 즉 flush()를 호출 할 필요 없다
BufferedWriter는 줄바꿈을 하려면 \r\n을 추가해주거나
newLine()메서드를 호출 해야 하지만
PrintWriter는 줄바꿈을 지원하는 println(String str)메소드를
제공한다
즉 문자 기반으로 입출력시 BufferedReader읽고
PrintWriter출력하면 편하다
*/
PrintWriter pw = new PrintWriter(System.out,true);
//br로 읽고 pw로 출력
while((data = br.readLine()) != null) {
//플러쉬 불필요,브릿지 사용 불필요,줄바꿈 불필요
pw.println(data);
}
}/////////////main
}////////////////class
BufferedRWKeyboardToFile.java
package io24.filter;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import common.utility.CommonUtil;
public class BufferRWKeyboardToFile {
public static void main(String[] args) throws IOException {
/*
//1]필터끼운 입력 스트림 생성
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
//2]필터 끼운 출력 스트림 생성
PrintWriter pw =
new PrintWriter(
new FileWriter("src/io24/filter/KeyboardChar.txt"),true);
//3]br로 읽고 pw로 출력
String data;
while((data= br.readLine()) !=null) {
pw.println(data);
}
//4]스트림닫기
pw.close();*/
//Scanner클래스의 nextLine() 및 nextInt()메소드와 같은 내가 만든 메소드 테스트
System.out.println("이름을 입력하세요?");
System.out.println("당신의 이름:"+nextLine());
System.out.println("나이를 입력하세요?");
System.out.println("당신의 10년후 나이:"+(nextInt()+10));
}/////////main
/*Scanner클래스의 nextLine()이나 nextInt()같은 메소드 만들기*/
private static String nextLine() {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String input=null;
try {
input=br.readLine();
}
catch (IOException e) {e.printStackTrace();}
return input;
}
private static int nextInt() throws InputMismatchException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String input=null;
try {
input=br.readLine();
}
catch (IOException e) {e.printStackTrace();}
if(!CommonUtil.isNumber(input)) throw new InputMismatchException();
return Integer.parseInt(input);
}
}////////////class