Scanner (편리함!)
- 다양한 입력 소스 지원
(System.in), 파일이나 문자열 등 다른 소스에서도 데이터를 읽을 수 있음 - 다양한 데이터 유형 처리
정수, 실수 ,문자열 등 여러 유형의 데이터를 쉽게 읽을 수 있고 각 유형에 맞게 메소드를 사욯애서 데이터 처리할 수 있다 - 유효한 데이터 추출
유효한 형식인지 확인하여 유효하지 않은 데이터를 입력했을 때, 에외를 발생시킨다 - 간편한 사용
- 메모리 누수방지
s.close()를 사용하여 누수를 방지할 수 있다
BufferedReader (성능!)
- 버퍼링
버퍼를 이용하여 데이터를 읽어옴, 데이터를 한 번에 읽어와서 버퍼에 저장한 후, 필요할 때마다 버퍼에서 데이터를 읽어온다 - 한 줄씩 읽기
readLine()메소드를 통해 데이터를 한 줄씩 읽어올 수 있다
텍스트 파일이나 네트워크 연결에서 한 줄씩 데이터를 읽을 때 특히 유용하다
readLine()은 읽은 데이터를 String 형태로 반환하고, 데이터의 끝에 도달하면 null을 반환한다 - 문자 인코딩
생성자를 통해 InputStreamReader를 함께 사용하여 데이터의 인코딩을 지정할 수 있다. - 입출력 예외 처리
예외 처리 기능을 제공하여 발생하는 오류를 적절하게 처리가 가능하다 - 자동 리소스 관리
try-with-resources 문을 활용하여 자동 리소스 관리를 할 수 있다
Scanner는 띄어쓰기와 개행문자를 기준으로 입력 값을 인식하기 때문에 따로 가공할 필요가 없지만,
BufferedReader 는 개행문자(엔터)만 경계로 인식하고 입력된 데이터의 형식이 String으로 고정되기 때문에 데이터를 따로 가공해주어야 한다
BufferedReader와 StringTokenizer를 사용하기 위해 import를 해준다
BufferedReader를 사용하기 위해선 예외처리가 필수적이기 때문에 try, catch문을 이용 or 메인문 중괄호 시작 전 throws IOException으로 처리해야만 한다
입력을 받기 위해선 readLine() 메소드를 사용하고, 데이터가 문자 값으로 들어오기 때문에 숫자 값을 받아올 땐 꼭 형변환이 필요하다
단일 입력을 받을 때는 상관없지만 다량의 데이터를 입력받을 때는 split 아니면 StringTokenizer를 사용해준다
split은 입력받는 동시에 별다른 처리 없이 배열로 데이터를 받아올 수 있다, StringTokenizer의 경우 토큰화 된 문자열을 다시 처리해주어야 한다.
StringTokenizer의 생성자에서 추가적인 구분자를 명시하지 않을 경우 default 값은 띄어쓰기로 데이터가 구분되기 때문에 필요시 다른 구분자를 사용할 경우 StringTokenizer st = new StringTokenizer(문자열, 구분자); 를 이용한다.
배열을 생성하며 크기를 정해줄 땐 countTokens() 메소드를 이용해 총 토큰의 수를 리턴 받는다.
그다음 hasMoreTokens() 메소드가 토큰이 더 이상 없을 때 false를 리턴한다는 것을 이용해 while문을 돌리며 데이터를 저장한다.
성능면에선 split은 정규식을 기반으로 문자열을 자르는 로직으로 동작하기 때문에 단순히 공백 자리를 당겨서 채우는 StringTokenizer가 더 빠르다.
import java.io.*; //BufferedReader 사용
import java.util.*; //StringTokenizer 사용
public class BufferEx {
public static void main(String[] args) throws IOException { // 예외처리 필수
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
String s = br.readLine();
System.out.println("String : " + s);
int i = Integer.parseInt(br.readLine()); // readLine()으로 받은 String 값을 int로 형변환
System.out.println("Int : " + i);
//여러 개의 데이터 입력받기
String s2[] = br.readLine().split(" "); //split을 이용해 다량의 데이터 입력 받기
StringTokenizer st = new StringTokenizer(br.readLine());
int arr[] = new int[st.countTokens()];
int count=0;
while(st.hasMoreTokens()) {
arr[count] = Integer.parseInt(st.nextToken());
System.out.println(arr[count++]);
//countTokens() : 총 토큰의 개수를 리턴
//hasMoreTokens() : 토큰이 남아있다면 true, 없으면 false 리턴
}
}
}
출처: https://lasbe.tistory.com/48 [LasBe's Upgrade:티스토리]
예시)
성능향상스트림
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class test1 {
public static void main(String[] args) throws IOException {
FileWriter fw=new FileWriter("b.txt"); //b.txt파일이 생성됌
BufferedWriter out=new BufferedWriter(fw);
out.write("Halo");
out.newLine(); // = \\n
out.write("today is Friday");
out.newLine();
out.write("so exciting");
out.close();
}
}
문자입력 스트림 BuffredReader, Writer
import java.io.*;
public class test1 {
public static void main(String[] args) {
//FileReader f=new FileReader("b.txt");
//BufferedReader in=new BufferedReader(f);
try {
BufferedReader in = new BufferedReader(new FileReader("b.txt"));
String str;
while (true) {
try {
str = in.readLine();
if (str == null) {
break;
}
System.out.println(str);
} catch (Exception e) {}
}
try {
in.close();
} catch (IOException e) {
}
} catch(FileNotFoundException e){
}
}
}
/*
FileWriter fw=new FileWriter("b.txt"); //b.txt파일이 생성됌
BufferedWriter out=new BufferedWriter(fw);
out.write("Halo");
out.newLine(); // = \\n
out.write("today is Friday");
out.newLine();
out.write("so exciting");
out.close();
*/
예시)
Sample.txt파일에 “저는 자바를 좋아합니다”를 저장하고 파일을 읽어 화면에 출력해라 (String [] 배열로 초기화해서 for문으로 읽기)
import java.io.*;
public class test1 {
public static void main(String[] args) throws IOException {
// 파일 "Sample.txt"를 읽어오기 위해 BufferedReader를 생성합니다.
BufferedReader br=new BufferedReader(new FileReader("Sample.txt"));
// 3. 파일을 읽어옴
// 무한 루프를 통해 파일의 각 라인을 읽어옵니다.
for(;;){
// 한 줄씩 읽어옵니다.
String str=br.readLine();
// 만약 읽어온 라인이 null이라면 파일의 끝에 도달했으므로 반복문을 종료합니다.
if(str==null){
break;
}
System.out.println(str); //4. 출력
}
/*
파일에 문자열을 쓰는 코드입니다.
String str[] = {"저는 자바를 좋아합니다."};
// 파일 "Sample.txt"를 생성하기 위해 FileWriter를 생성합니다.
FileWriter fw = new FileWriter("Sample.txt"); //1. 파일생성
// BufferedWriter를 생성하여 문자열을 파일에 쓰기 위해 사용합니다.
BufferedWriter bw = new BufferedWriter(fw);
// 문자열 배열에 있는 각 문자열을 파일에 씁니다.
for (int i = 0; i < str.length; i++) {
bw.write(str[i]);
}
bw.close(); // 2.문자열 파일에 저장
*/
}
}
예시)
- FileOutputStream을 이용하여 byte [] 배열 속에 들어있는 바이너리 값을 fi.txt파일에 저장해라. (byte b []={1,2,3,4,5}; 로초기화)
- 저장한 후 값을 읽어와서 출력해라.
💡 readAllBytes를 사용하면 따로 byte로 변환 안 시켜줘도 된다!
import java.io.*;
public class test1 {
public static void main(String[] args) throws IOException {
// 파일 "fi.txt"를 읽기 위해 FileInputStream을 생성합니다.
FileInputStream fi = new FileInputStream("fi.txt"); //3.파일 읽기
// 파일의 모든 바이트를 읽어와서 byte 배열에 저장합니다.
byte c[] = fi.readAllBytes();
// 읽어온 바이트 배열을 반복문을 통해 출력합니다.
for (byte b : c) { //4.출력
System.out.println(b);
}
/*
// 파일에 바이트 배열을 쓰는 코드입니다.
FileOutputStream fw = new FileOutputStream("fi.txt"); //1.파일생성
byte b[]={1,2,3,4,5};
// 파일에 바이트 배열을 씁니다.
fw.write(b);
// 파일 출력 스트림을 닫습니다.
fw.close(); //2.문자열 파일에 저장
*/
}
}
예시) BufferedReader, StringTokenizer 활용한 알람시계 맞추기
- 일어나야 하는 시간 보다 45분 일찍 맞추기
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int H = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
if(M<45){
H = (H == 0)? 23:H-1;
M = 60 - (45 - M);
} else {
M = M -45;
}
System.out.println(H+" "+M);
}
}
BufferedReader에서 입력종료시키기
IntelliJ에서는 eclipse와 같은 프롬프트나 터미널 환경에서 입력을 종료시키는 Ctrl + Z 를 사용 할 수 없으므로 특정 조건을 줘서 입력을 종료받아야함
예시1) end를 입력하여 종료시키기
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int sum = 0;
int count = 0;
System.out.println("정수를 입력하고 엔터를 누르세요. 입력을 종료하려면 'end'를 입력하세요.");
while (true) {
try {
String input = br.readLine(); // compareTo를 사용하여도 가능
if ("end".equals(input)) { // == if (input.compareTo("end")==0) {
break; //
}
int number = Integer.parseInt(input); //
sum += number; //
count++; //
}catch (Exception e){}
}
double avg = (double)sum/count;
System.out.println(avg);
}
}
예시2) 0을 입력하여 종료시키기
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
int sum = 0;
int count = 0;
System.out.println("정수를 입력하세요, 0을 입력하면 종료");
while(true){
try{
int num = Integer.parseInt(br.readLine());
if(num==0) {
break;
}
sum +=num;
count++;
}catch (Exception e){}
}
double avg = (double)sum/count;
System.out.println(avg);
}
}
'Language > JAVA' 카테고리의 다른 글
[JAVA] notion 링크 (0) | 2024.04.22 |
---|---|
[JAVA] 다형성 역할과 구현 ★ (0) | 2024.03.10 |
[JAVA] Split / StringTokenizer 비교 (0) | 2024.03.09 |
[JAVA] 종합예시 (0) | 2024.03.08 |
[JAVA] 객체배열 (1) | 2024.03.08 |