java

19일차 2023-04-03

choi Hoon 2023. 4. 3. 19:47

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