복습
자바 16일차 - 표준 입출력, 바이트 단위 스트림 본문
표준 입출력 클래스
: 화면을 출력하고 입력받는 클래스로 자바에서 미리 정의되어 있다. 프로그램이 시작될 때 자동으로 생성되므로 자주 사용하는 System.out도 별도로 생성하지 않고 사용할 수 있었다.
System.in - 표준 입력, System.out - 표준 출력, System.err - 빨간색 오류메시지를 띄움
System.in으로 입력받기
이전에 사용했던 코드로 System.in.read()를 써서 값을 받아온다. 결과창에서 값을 입력하면 바이트 단위로 읽어온다. 결과를 보면 ABC를 입력했지만 1바이트만 읽어오므로 A만 인식되었고, i값을 그대로 출력하면 A의 아스키코드인 65가 출력되고 char를 써서 문자형으로 출력하면 A가 출력된다.
문자 여러개 입력받기
똑같은 방법이지만 while문을 넣어서 여러개의 문자를 읽어온다. read()메서드는 값을 계속 읽어오다가 읽어올 값이 없으면 -1을 반환하므로 -1이 되면 while문을 빠져나오게 한다. 결과는 여러개의 문자를 입력해도 그대로 출력되는 것을 볼 수 있다.
여러가지 입력클래스
Scanner 클래스
: java.util 패키지에 있는 입력 클래스로 문자뿐 아니라 실수, 정수 등 다른 자료형도 읽을 수 있으며, 파일이나 문자열을 생성자의 매개변수로 받아 읽어올 수 있다.
기본적인 형식 : Scanner scanner = new Scanner(System.in) -> 표준 입력으로 부터 자료를 읽어옴.
Scanner 클래스를 생성하고 nextLine()메서드로 문자열인 이름, 직업을 입력받고, nextInt()메서드로 정수형인 사번을 입력받는다. 그리고 각각을 출력했다.
*기존의 System.in.read()는 입출력 예외처리 때문에 try-catch문이나 throw을 사용했지만 Scanner 클래스는 예외처리 항목이 구현되어 있으므로 그냥 사용한다.
Console 클래스
: System.in 을 사용하지 않고 간단히 콘솔 내용을 읽을 수 있는 클래스
Console 클래스는 이클립스와는 연동되지 않기 때문에 실행하면 위와 같이 에러가 발생한다. 그러므로 오른쪽 위의 사진처럼 cmd 창에서 파일을 불러와 사용한다. 결과는 위의 Scanner 클래스와 같다. console 에서는 readLine()메서드를 사용하여 값을 받아오고, readPassword() 메서드를 이용하여 비밀번호를 받아올 수도 있다.
바이트 단위 스트림
FileInputStream
: 파일에서 바이트 단위로 자료를 읽어 들일 때 사용하는 클래스
13행에서 스트림을 생성하였다. input.txt라는 ABC라는 파일을 read()메서드를 통해 1바이트씩 값을 읽어온다. A, B ,C 를 읽어오는데 그냥 출력하게 되면 아스키코드값이 출력되고 16행처럼 char를 이용하면 문자인 C로 출력된다. 이 예제에서는 finally문에서 close()메서드로 스트림을 닫아준다. 만약 스트림이 생성되지 않았다면 NullPointerException이 발생하여 24행에서 예외를 처리한다.
파일 끝까지 읽기
위의 예제는 read()메서드를 3번 사용하여 3개의 문자열을 읽어왔다. 하지만 여기서는 while문을 사용하여 파일안에 있는 모든 문자열을 읽어온다. System.in에서와 마찬가지로 read()메서드는 읽어올 값이 없으면 -1을 반환하므로 -1이되면 while문을 빠져나오고 End 문구가 출력된다. 따라서 결과는 ABCDEFGHI라고 되있는 input.txt 파일을 while문을 사용하여 차례대로 출력하고 마지막에 End 문구가 출력되었다.
배열을 사용하여 한꺼번에 여러 문자 읽어오기
(input2.txt 파일에는 A~Z 까지의 문자가 입력되어 있다.)
int read(byte[] b) 메서드를 사용하면 선언한 바이트 배열의 크기만큼 한꺼번에 자료를 읽어오고, 자료의 수를 반환한다. 코드를 보면 크기가 10인 배열을 만들고 while문을 사용하여 배열 bs에 모든 값을 읽어온다. 배열 bs의 크기는 10이므로 10개의 문자를 읽어온 후 문자를 출력하고 for문을 빠져나가 읽어온 자료의 수를 출력한다. 그리고 모든 자료를 읽어올 때 까지 반복한 후 end 문구가 출력된다. 여기서 결과를 보면 마지막에 6바이트를 읽어온 후 Z로 끝나야 하지만 QRST가 더 출력된 것을 볼 수 있다. 이는 6바이트를 읽어온 후 읽어올 값이 없으므로 기존에 읽어온 QRST가 출력된 것이다.
이를 해결하기 위해 13,14행의 for-each 문만 원래의 for문 형식으로 바꿔주어 바이트 수만큼 출력하도록 하면 위와 같은 결과가 출력된다.
FileOutputStream
: 파일에 바이트 단위 자료를 출력하기 위해 사용하는 스트림
try-with-resources 문을 이용하여 리소스 값에 스트림을 생성하였고, 스트림은 output.txt 파일에 자료를 출력한다. write()메서드를 이용하여 아스키 값인 65, 66, 67을 입력하였고 output.txt 파일에는 ABC가 출력되고 결과창에 완료 문구가 출력된다. 여기서 코드를 한 번더 실행하면 ABC가 더해져서 출력되는 것이 아니라 기존의 값이 없어지고 다시 ABC가 입력되게 된다. 아래 예제에서 기존 자료에서 이어서 출력하는 것을 구현했다.
true 사용하기
위의 예제에서와 같은 코드를 사용하고, 아래에는 그 코드를 복사하여 파일명 옆에 ,를 사용하여 true를 적어주어 기존값에 이어서 ABC가 더해져서 출력되게 된다.
파일에 배열로 출력하기
입력스트림과 마찬가지로 배열을 사용한다. 크기가 26인 배열을 만들고 data 변수의 초기값을 65로 선언한다. 이는 A의 아스키 값이다. 그 다음 for문을 사용하여 배열에 아스키 값을 65부터 차례대로 Z의 아스키 값까지 대입한 후 write(bs)를 써서 배열 bs의 값을 output2.txt 파일에 출력하여 위와 같은 결과가 나왔다.
* 여기서도 마찬가지로 true를 사용하면 기존자료에 이어서 값을 출력할 수 있다.
구간설정
이 코드는 위와 동일하지만 write() 메서드를 사용할 때 출력하는 구간을 설정해주었다.
write(배열이름, 인덱스번호, 길이); 형식으로 입력하면 배열의 원하는 구간을 출력할 수있다. 따라서 인덱스2(3번째) 값인 C부터 L까지 10개의 문자가 출력되었다.
문자단위스트림
FileReader
: FileInputStream과 동일하지만 문자단위로 자료를 읽어온다.
reader.txt에는 "안녕하세요"라는 문구가 입력되어 있다. FileInputStream 예제와 사용방법은 동일하지만 여기서는 문자단위로 값을 읽어와서 한글인 안녕하세요 문구가 정상적으로 출력된다. 바이트 단위인 FileInputStream을 사용했다면 한글은 2바이트 이므로 값이 깨져서 출력되었을 것이다.
FileWriter
: FileOutputStream과 동일하지만 문자단위로 값을 출력한다.
FileOutputStream과 사용방식은 동일하며 여러 문자열을 write()메서드로 입력한 결과가 출력된 것을 볼 수 있다.
보조스트림
Buffered스트림
: 내부적으로 8,192바이트 크기의 배열을 가지고 있어 생성된 스트림에 배열 기능을 추가하여 더 빠르게 입출력을 실행할 수 있다.
버퍼를 사용하지 않았을때
try-with-resources 문을 사용하여 FileInputStream과 FileOutputStream을 생성한다. 그리고 currentTimemillis()메서드로 현재시간을 측정한 후 while문으로 a.zip파일을 가져와서 copy.zip 파일로 복사한다. 그 후의 시간에서 이전에 측정한 시간을 빼서 걸린시간을 문구와 함께 출력한다. 약 17초가 걸린 것을 볼 수 있다.
버퍼를 사용했을 때
위와 똑같은 코드에서 버퍼 input,output 스트림을 추가하여 버퍼를 이용하여 파일을 복사했다. 그 결과 이전과 비교했을 때 시간이 엄청나게 줄어든 것을 볼 수 있다.
'자바' 카테고리의 다른 글
자바 18일차 - 소코반 만들기 (0) | 2020.04.10 |
---|---|
자바 17일차 - 직렬화, 나머지 입출력클래스, HEX코드 불러오기 (0) | 2020.04.09 |
자바 15일차 - 스트림 활용, 예외처리 (0) | 2020.04.07 |
자바 14일차 - Map인터페이스, 내부 클래스, 람다식, 스트림 (0) | 2020.04.06 |
자바 13일차 - 컬렉션 프레임워크(List, LinkedList, Set, HashSet, TreeSet, Comparator (0) | 2020.04.03 |