보조 스트림은 다른 스트림에게 스트림을 전달하는 기능이다.
일반적으로 스트림 자체가 기능이 하나만 특화되어 매우 한정적인데
다른 스트림에 전달 함으로써 다른 기능을 사용 할 수 있다.
하지만 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(); }
'개념 및 코딩 > 09.Java IO' 카테고리의 다른 글
[JAVA]09-05.Files, FileSystem, Path, WatchService, File Read,write,copy (0) | 2018.09.27 |
---|---|
[JAVA]09-04.보조 스트림 : DataStream, ObjectStream, PropReader Writer (0) | 2018.09.27 |
[JAVA]09-02.File, File Reader, File Writer (0) | 2018.09.27 |
[JAVA]09-01.InputStream, OutputStream, Console, Scanner (0) | 2018.09.21 |
[JAVA]09-01.Stream (0) | 2018.09.11 |