보조 스트림은 다른 스트림에게 스트림을 전달하는 기능이다.


일반적으로 스트림 자체가 기능이 하나만 특화되어 매우 한정적인데


다른 스트림에 전달 함으로써 다른 기능을 사용 할 수 있다.


하지만 Stream 선언이 늘어 난 만큼 close로 해제도 제때 해주어야 한다.


다음 예제는 File Stream을 Input, Output Stream에 전달한 예제이다.



package chap11.exam08.string;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

public class TextFileCopy {

	public static void main(String[] args) throws Exception {
		// 1. 경로 설정
		String ori = "C:/img/asd.txt";
		String target = "C:/img/temp/asd.txt";
				
		// 2. 스트림 준비
		// 보조스트림 - 바이너리 기반의 스트림에 문자열 특화 기능 추가
		FileInputStream fis = new FileInputStream(ori);
		InputStreamReader reader = new InputStreamReader(fis, "UTF-8");
		
		FileOutputStream fos = new FileOutputStream(target);
		OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8");
		
		// 3. 읽어오기
		char[] arr = new char[100];
		while(reader.read(arr) != -1) {
			writer.write(arr);	// 4. 내보내기
		}

		// 5. 자원반납(flush, close)
		writer.flush();
		reader.close();
		writer.close();
		fis.close();
		fos.close();
		
	}

}






기존의 스트림이 하나씩 하나씩 데이터를 들고 왔다면


Buffer Stream은 데이터를 한꺼번에 여러개씩 들고, 한꺼번에 전송 할 수 있도록 해 주는 임시 저장소이다.


그만큼 속도도 확연하게 차이나게 된다.


다음 예제는 데이터를 하나씩 받았을 때와 


Buffer Stream을 이용해 Byte 배열 덩어리로 한꺼번에 받았을 때의 속도를 비교하는 코드이다.


TimeChecker chk = new TimeChecker는 클래스 파일을 새로 만들어 선언한 클래스이고, 시간을 체크하는 기능을 간단하게 만들었다.


버퍼를 사용하지 않을 때


package chap11.exam09.buffer;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class BufferNotUse {

	public static void main(String[] args) throws Exception {

		TimeChecker chk = new TimeChecker();
		// 1. 파일 위치 지정
		String ori = "C:/img/10multi.pdf";
		String target = "C:/img/temp/NotuseCopy.pdf";
		
		// 2. 스트림 준비
		FileInputStream fis = new FileInputStream(ori);
		FileOutputStream fos = new FileOutputStream(target);
		int data;
		chk.timeStart();
		
		// 3. 읽기
		while((data = fis.read()) != -1) {
			System.out.println("복사중...");
			fos.write(data); // 4. 쓰기(시간 체크)
		}
		
		// 5. 비우고 반납
		fos.flush();
		// 15667ms 걸림, 15.6초
		System.out.println("완료 : " + chk.timeStop() + " ms");
		fis.close();
		fos.close();
	}

}


버퍼를 사용 할 때


package chap11.exam09.buffer;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.Buffer;

public class BufferUse {
	
	// try-with-resource == 트라이문이 끝나면 아래에 소켓 버퍼 등 close를 할 필요가 없음.
	public static void main(String[] args) throws Exception {
		TimeChecker chk = new TimeChecker();
		// 1. 파일 위치 지정
		String ori = "C:/img/10multi.pdf";
		String target = "C:/img/temp/useCopy.pdf";
		
		// 2. 스트림 준비(보조 스트림)
		try(  // 트라이가 끝나면 자동으로 close가 된다.
				FileInputStream fis = new FileInputStream(ori);
				BufferedInputStream bis = new BufferedInputStream(fis);
				
				FileOutputStream fos = new FileOutputStream(target);
				BufferedOutputStream bos = new BufferedOutputStream(fos);
			){
			byte[] arr = new byte[1024];
			chk.timeStart();
			while(bis.read(arr) != -1 ) {
				bos.write(arr);
			}
			// 5. 비우고 반납
			bos.flush();
			// 15667ms 걸림, 15.6초
			// 6044ms 걸림, 6초 (data를 배열로 받지 않았을 때)
			// 4ms 걸림, 0.004초 (byte[]배열로 받았을 때)
			System.out.println("완료 : " + chk.timeStop() + " ms");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	
//	public static void main(String[] args) throws Exception {
//
//		TimeChecker chk = new TimeChecker();
//		// 1. 파일 위치 지정
//		String ori = "C:/img/10multi.pdf";
//		String target = "C:/img/temp/useCopy.pdf";
//		
//		// 2. 스트림 준비(보조 스트림)
//		FileInputStream fis = new FileInputStream(ori);
//		BufferedInputStream bis = new BufferedInputStream(fis);
//		
//		FileOutputStream fos = new FileOutputStream(target);
//		BufferedOutputStream bos = new BufferedOutputStream(fos);
//		
//		byte[] arr = new byte[1024];
//		chk.timeStart();
//		while(bis.read(arr) != -1 ) {
//			bos.write(arr);
//		}
//		
//		
//		
//		
//		
//		
//		
//		
////		int data;
////		chk.timeStart();
////		
////		// 3. 읽기
////		while((data = bis.read()) != -1) {
////			System.out.println("복사중...");
////			bos.write(data); // 4. 쓰기(시간 체크)
////		}
//		
//		// 5. 비우고 반납
//		bos.flush();
//		// 15667ms 걸림, 15.6초
//		// 6044ms 걸림, 6초 (data를 배열로 받지 않았을 때)
//		// 4ms 걸림, 0.004초 (byte[]배열로 받았을 때)
//		System.out.println("완료 : " + chk.timeStop() + " ms");
//		bos.close();
//		bis.close();
//		fis.close();
//		fos.close();
//	}

}


시간을 체크 할 타이머


package chap11.exam09.buffer;

public class TimeChecker {
	long start = 0;
	long end = 0;
	
	public void timeStart() {
		start = System.currentTimeMillis();
	}
	
	public long timeStop() {
		end = System.currentTimeMillis();
		return end-start;
	}
}



2번째 코드에서 try catch 문의 try 앞에 괄호가 추가 되었는데


괄호 안에 Stream을 선언하였을 경우 


try catch문이 끝났을 때 자동으로 close, 해제가 된다. (아래 복사)



		// 2. 스트림 준비(보조 스트림)
		try(  // 트라이가 끝나면 자동으로 close가 된다.
				FileInputStream fis = new FileInputStream(ori);
				BufferedInputStream bis = new BufferedInputStream(fis);
				
				FileOutputStream fos = new FileOutputStream(target);
				BufferedOutputStream bos = new BufferedOutputStream(fos);
			){
			byte[] arr = new byte[1024];
			chk.timeStart();
			while(bis.read(arr) != -1 ) {
				bos.write(arr);
			}
			// 5. 비우고 반납
			bos.flush();
			// 15667ms 걸림, 15.6초
			// 6044ms 걸림, 6초 (data를 배열로 받지 않았을 때)
			// 4ms 걸림, 0.004초 (byte[]배열로 받았을 때)
			System.out.println("완료 : " + chk.timeStop() + " ms");
			
		} catch (Exception e) {
			e.printStackTrace();
		}





+ Recent posts