0. Java의 인코딩
- Java는 String을 처리할 때 내부(메모리상)에서는 UTF-16 BE 인코딩으로 문자열을 저장하고,
송수신에서는 직렬화가 필요한 경우 변경된 UTF-8(modified UTF-8)을 사용하며 문자열을 입/출력할 때에만 사용자가 지정한 인코딩 값 또는 운영체제의 기본 인코딩 값으로 문자열을 인코딩한다. - 이클립스의 File encoding이 UTF-8 이라면
- 입력(UTF-8) → 송수신(modified UTF-8) → 자바 메모리(UTF-16) → 송수신(modified UTF-8) → 출력(UTF-8)
1. InputStream 과 System.in
- 데이터 흐름을 스트림이라고 한다.
- 스트림은 단방향이기 때문에 입력과 출력 동시에 발생할 수 없다
- 자바에서 가장 기본이 되는 입력 스트림은 InputStream / 출력 스트림은 OutputStream
- 컴퓨터의 모든 데이터는 바이트 단위 데이터로 구성 되어 있다. 그래서 InputStream은 바이트 단위로 데이터를 보내며 이 InputStream의 입력 메소드인 read()는 1바이트 단위로 읽어들인다.
- 만약 입력받은 문자가 2byte 이상으로 구성되어있는 인코딩을 사용할 경우 1byte 값만 읽어들이고 나머지는 읽지 않고 스트림에만 남아있기 때문에 출력할 때는 해당 데이터의 1byte에 대한 인코딩 값을 10진수로 변환한 값이 출력되는 것이다.
- 예를 들어 10000001 11110000 의 값을 갖고 있는 2byte 문자를 하나를 입력했다고 가정해보자.
1byte로 각각 나뉘어 스트림을 통해 10000001 11110000 의 데이터가 흐르게 된다. 즉, 스트림에서는 1byte 데이터가 2개가 있다는 의미다
하지만 프로그램에서는 read() 한번만 쓰면 먼저 입력된 10000001 을 읽지만, 11110000 은 스트림에 계속 남아있게 된다. 만약 나머지 1byte도 읽고 싶다면 read() 메소드를 두번 써야된다.
InputStream의 가장 큰 특징 두가지
1. 입력받은 데이터는 int형으로 저장되는데 이는 10진수의 UTF-16 값으로 저장된다.
2. 1 byte만 읽는다.
System.in
- System.in 이 InputStream 타입
- 간략하게 말하면 키보드로 치거나 터미널 등에서 입력을 넣어주는 것들은 System.in을 통해 연결된다는 의미이다.
- in 이라는 변수는 InputStream의 변수로 InputStream타입의 새 변수를 선언하고 그 변수에 System.in을 할당시킬 수도 있다는 뜻이다.
import java.io.IOException;
import java.io.InputStream;
public class Input_Test {
public static void main(String[] args) throws IOException {
InputStream inputstream = System.in;
int a = inputstream.read();
System.out.println(a);
}
}
- InputStream 타입의 변수를 생성하고 입력을 받은 메소드인 read()를 통해 입력할 수 있다.
주의할점
기본적으로 입출력 클래스는 java.io 라는 패키지에 있다. 그리고 반드시 예외처리를 해주어야한다.
try-catch문으로 예외처리 하거나
throws IOException으로 처리해줘도 된다
Scanner 나 System.out.print 메소드 경우, 해당 메소드 안에 자체적으로 예외처리를 하기 때문에 예외처리를 해 줄 필요가 없었지만
기본적으로 io 패키지는 IOException 이라는 예외를 던지기 때문에 이를 처리해주어야 정상적으로 컴파일 된다.
InputStreamReader(문자스트림)
- 바이트 단위로 읽어 들이는 형식을 문자단위(character)로 데이터로 변환시키는 중개자 역할을 한다고 보면 된다.
- '문자'를 처리하지 '문자열'이 아니다
- 바이트스트림인 InputStream을 통해 입력을 받으면 문자스트림인 InputStreamReader을 통해 바이트 단위 데이터를 문자(character) 데이터로 처리할 수 있게 만들어 준다
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Input_Test {
public static void main(String[] args) throws IOException {
InputStream inputstream = System.in;
InputStreamReader sr = new InputStreamReader(inputstream);
}
}
더 간단하게 사용하는 방법
InputStreamReader sr = new InputStreamReader(System.in);
InputStreamReader의 가장 큰 특징
1. 바이트 단위 데이터를 문자(character) 단위 데이터로 처리할 수 있도록 변환해준다.
2. char 배열로 데이터를 받을 수 있다.
Scanner
- java.util 패키지 내에 포함된 클래스
- 느린 이유 : 입력을 읽는 과정에서 정규 표현식을 적용하고, 입력값 분할 파싱과정을 스스로 제공해주기 때문에
BufferedReader
- java.io 패키지 내에 포함된 클래스
- InputStreamReader 에 버퍼링 기능이 추가된 클래스
- 모든 입력을 Char형으로 리턴, 버퍼를 사용하여 받는다.
- System.in 은 바이트스트림인 InputStream 타입이고 이 입력방법만으로는 문자를 온전하게 받기 힘드니 InputStreamReader로 감싸주면서 바이트 단위 데이터를 문자 단위로 처리할 수 있도록 한다고 한다
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//위 코드 풀면
InputStream inputstream = System.in;
InputStreamReader sr = new InputStreamReader(inputstream);
BufferedReader br = new BufferedReader(sr);
- InputStreamReader로 char type으로 처리할 수 있는 장점은 개선 되었지만 만약 문자열로 입력하고 싶다면 매번 배열을 선언해야 한다는 단점은 그대로 남아있다. 심지어 입력받을 문자열의 길이가 가변적이라면 더욱 불편하다.
- 그래서 쓰는 것이 Buffer(버퍼)를 통해 입력받은 문자를 쌓아둔 뒤 한 번에 문자열처럼 보내는 것이다.
- BufferedReader를 쓸 때 입력 메소드로 readLine()을 많이 쓴다.
- 이 메소드는 한 줄 전체를(공백 포함) 읽기 때문에 char 배열을 하나하나 생성할 필요 없이 String으로 리턴하여 바로 받을 수 있다는 장점이 있다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- System.in = InputStram → InputStreamReader → BufferedReader
- byte 타입으로 읽어들인 in을 char타입으로 처리한 뒤 String,즉 문자열로 저장할 수 있게 한다는 의미로 해석
BufferedReader의 특징
1. 버퍼가 있는 스트림이다.
2. 별다른 정규식을 검사하지 않는다.
getBytes()
- 문자열을 입력받을 때 해당 문자열을 쉽게 각 자릿값을 반환받을 수 있는 방법
- java.lang.string 패리지에 있는 메소드로 따로 import 할 필요 없이 사용할 수 있다.
- String(문자열)에 대하여 해당 문자열을 하나의 byte 배열로 변환해주는 메소드이다.
- 변환되는 방법은 UTF-16 인코딩으로 변경되는 값을 따른다.
- UTF-16(유니코드)의 앞부분은 아스키코드와 호환되기 때문에 영어문자 및 숫자가 같다
출처
https://st-lab.tistory.com/41?category=830901
'이론 > 자바' 카테고리의 다른 글
[Java] MyBatis (0) | 2024.09.23 |
---|---|
[Java] 클래스,객체, 인스턴스 차이 (0) | 2024.09.20 |
[Java] 자바 메모리 구조, JVM (0) | 2024.09.18 |
[Java] JVM 메모리 구조 - 런타입 데이터 영역(Runtime Data Area) (2) | 2024.09.18 |
[Java] Wrapper Class (0) | 2024.09.05 |