바이트 스트림 Byte Streams ?

- 스트림의 기본 입출력 단위는 바이트(Byte) 이다.

- 1바이트 (8bit) 단위로 입출력을 수행한다.

- 2진 데이터의 입출력이 가능하다.

- 모든 바이트 스트림 클래스는 InputStream 및 OutputSream클래스의 서브 클래스이다.

 

public class Ex01_InputStream {
	public static void main(String[] args) {
		int data; // 4byte 자료형
		char ch; // 2byte 자료형
		
		try {
			System.out.println("문자열 입력[ctrl+z:종료] ? ");
			while ((data = System.in.read()) != -1) {
            	// System.in.read() 로는 1byte만을 읽는다.
            
				// System.out.println(data); // 입력받은 ASCII코드 값 출력
				// System.out.write(data);
					// 4byte(data) 중 하위 1byte만 출력하며 한글도 잘 출력된다.

				ch = (char)data;
				// System.out.print(ch);
					// 한글은 깨져나옴. 2byte문자를 1byte만 읽어서 2byte(ch의 자료형)로 출력하므로
				
				System.out.write(ch);
					// 한글 안깨짐. 2byte중 하위 1byte만 출력
                    // 즉, 1바이트 읽음 -> 읽은 1바이트를 2바이트로 바꿈 -> 1바이트로 읽음
                    // 따라서 안깨짐
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}

System.in 은 InputStream의 객체로 byte 스트림이다.

InputStream의 read() 메소드 : 1byte문자를 읽어들여 ASCII코드값을 반환한다.

키보드의 Enter 키는 ASCII 코드의 13(Carriage Return)과 10(Line Feed)를 의미한다. ( 앞으로 와서 줄을 바꿈)

 

자바에서 한글은 한글자에 2byte이다.

 

UTF-16 순수차바 처리 방식으로 한글 2byte, 영어 2byte로 처리한다.

UTF-8 은 오라클 처리 방식으로 대부분의 웹, 리눅스 기본세팅, 맥 등에서 사용된다. 한글 3byte, 영어 1byte로 처리한다.


입력받은 수 까지의 합을 구하는 프로그램

13은 엔터를 의미함.

public class Ex02_InputStream {

	public static void main(String[] args) {
		int n, data;
		n = 0;
		// 12엔터 => 49 50 13 10
		try {
			System.out.print("수 ? ");
			while ((data = System.in.read()) != 13) {
				data = data - 48;
				n = n * 10 + data;
			}

			int s = 0;
			for (int i = 1; i <= n; i++) {
				s += i;
			}
			System.out.println("결과:"+s);

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

read() 는 키보드로 입력받은 문자를 ASCII 코드 값으로 반환해줌. 따라서 내가 입력한 것이 숫자여도 처리될 때는 숫자를 입력받은 것이 아닌 문자를 입력받았다고 처리된다. 그래서 문자 1의 ASCII값은 49이므로 48을 빼준 것.


public class Ex03_InputStream {

	public static void main(String[] args) {
		int data;
		
		try {
			System.out.println("ABCDEF 입력 후 엔터");
			data = System.in.read(); // 65
			System.out.write(data); // A
			 // write() 1byte를 보냄. 출력버퍼로 데이터를 보내서 출력.
			System.in.skip(2); // 읽어서 버림. BC
			
			data = System.in.read(); // 68
			System.out.write(data); // D
			
			System.in.skip(4); // EF엔터 버림
			
			System.out.flush(); // 출력 버퍼의 내용을 출력 장치로 보내줌.
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

read() 메소드에서 문자를 입력 받아 ASCII 코드 값으로 바꿔준다. (1바이트) 그 읽은 값들을 write() 메소드가 받아서 출력버퍼로 보내주면 후에 버퍼의 내용이 출력 장치로 가게됬을 때 표시된다.

data 에는 ABCDEF 이 스트림이 순서대로 넣어진다.

write() 메소드도 1byte를 읽는 메소드이기 때문에 먼저 읽은 1바이트 65가 출력 버퍼로 보내지고, 2바이트에 해당하는 BC는 skip() 메소드가 읽어서 버리고, 다시 read() 메소드가 1바이트를 읽어 아스키코드 값을 data에 넘겨주고 write()메소드가 1바이트를 읽어 D를 출력한다. EF와 엔터(2byte)는 skip() 메소드에 의해 읽어서 버려진다.

마지막에 flush() 메소드를 통해 출력 버퍼의 내용이 출력 장치로 보내지고, 화면에 보이게 된다. 


1. 증가 2. 감소 3. 종료

선택 =>

public class Ex04_InputStream {

	public static void main(String[] args) {
		boolean run = true;
		int speed = 0;
		char key;
		
		try {
			while(run) {
				do {
					System.out.println("1.증가 2.감소 3.종료");
					System.out.print("선택=>");
					key = (char)System.in.read();
					System.in.skip(2); // 엔터 버리기
				} while(key <'1' || key>'3');
				
				switch(key) {
				case '1':speed++;break;
				case '2':speed--;break;
				case '3':run=false;break;
				}
				System.out.println("speed:"+speed+"\n");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

read() 메소드가 1byte를 읽으면 ASCII값으로 49을 반환하는데 이것을 2byte로 char형인 key에 형변환해서 저장함. char형에서 49는 문자 '1'과 같은 의미이므로 switch(key) 에 '1' 이면 speed++; 해주고 '2'면 speed--; 해주고 '3'이면 종료한다.

 

근데 여기서 123 입력하면 23이 skip 되는거고 엔터는 아직 안읽었기 때문에 speed를 출력 후에 저렇게 문자가 출력된다. 

여기서는 23이 skip되고 3은 남아있었기 때문에 다음에 3을 바로 읽고 종료가 된다.

 

+ Recent posts