자바로 파일을 복사하는 프로그램을 코딩해보자.

 

1) 잘못된 예

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class FileCopyEx1 {

	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		// 키보드로 입력을 받는다.
		String source, dest;
		
		FileOutputStream fos = null;
		FileInputStream fis = null;
		
		try {
			System.out.print("복사할 원본 파일명 ? ");
			source = br.readLine();
			
			System.out.print("복사시킬 대상 파일명 ? ");
			dest = br.readLine();
			
			fis = new FileInputStream(source);
			fos = new FileOutputStream(dest);
			
			// 잘못 코딩한 예 - 서울에서 부산을 걸어서 가는 꼴
			int data;
			while( (data = fis.read()) != -1) {
				fos.write(data);
			}
			fos.flush();
			System.out.println("파일 복사 완료...");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if ( fis != null) {
				try {
					fis.close();
				} catch (Exception e2) {
				}
			}
			if ( fos != null) {
				try {
					fos.close();
				} catch (Exception e2) {
				}
			}
		}
		
		
	}

}

 

2) 효율적인 방식

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class FileCopyEx2 {

	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		// 키보드로 입력을 받는다.
		String source, dest;
		
		FileOutputStream fos = null;
		FileInputStream fis = null;
		
		byte[] b = new byte[4096];
		int len;
		
		try {
			System.out.println("파일 복사...");
			
			System.out.print("복사할 원본 파일명 ? ");
			source = br.readLine();
			
			System.out.print("복사시킬 대상 파일명 ? ");
			dest = br.readLine();
			
			fis = new FileInputStream(source);
			fos = new FileOutputStream(dest);
			
			long s = System.currentTimeMillis();
			// len = fis.read(b) => 최대 바이트배열 b길이 만큼 읽어 b에 저장하고
			// 실제로 읽어 들인 byte수를 반환
			while( (len = fis.read(b)) != -1) {
				fos.write(b, 0, len); // b배열의 0번째 인덱스부터 len개 저장
			}
			fos.flush();
			long e = System.currentTimeMillis();
			
			System.out.println("파일 복사 완료..." + (e-s)+"ms");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if ( fis != null) {
				try {
					fis.close();
				} catch (Exception e2) {
				}
			}
			if ( fos != null) {
				try {
					fos.close();
				} catch (Exception e2) {
				}
			}
		}
		
		
	}

}

ABCDEF 가 파일에 있어서 이 문자들을 읽어서 다른 파일에 붙일때, A를 읽으면 다시 A를 읽지 않는다. 

읽은 것은 다시 읽지 않는다! 그래서 배열에 인덱스 없이도 알아서 다 들어갔다가 다음 배열에 또 들어가고 그렇게 되는 것이다.

FileInputStream 클래스

- 파일 시스템의 파일로 부터 파일 내용을 바이트 스트림으로 읽어 들이기 위해 사용된다.

- InputStream 클래스의 하위 클래스

- 파일이 존재하지 않으면 FileNotFoundException 예외가 발생

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Ex13_FileInputStream {

	public static void main(String[] args) {
		String pathname = "test2.txt";
		int data;
		FileInputStream fis = null;

		try {
			fis = new FileInputStream(pathname);
				// FileInputStream : 파일 입력 byte 스트림
				// 만약 파일이 존재하지 않으면 fileNotFoundException 발생
			
			// FileNotFoundException < IOException < Exception
			System.out.println(pathname+" 파일 내용...");
			
			while( (data = fis.read()) != -1) {
				// 파일에서 읽은 내용을 화면에 출력
				System.out.write(data);
			}
			System.out.flush();
		} catch (FileNotFoundException e) {
			// 파일이 존재하지 않는 경우
			// e.printStackTrace();
			System.out.println(pathname + "는/은 존재하지 않는 파일 입니다.");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(fis != null) {
				try {
					fis.close();
				} catch (Exception e2) {
				}
			}
		}
	}

}

위와 같은 의미

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Ex14_FileInputStream {
	public static void main(String[] args) {
		String pathname = "text.txt";
		int data;
		
		try(FileInputStream fis = new FileInputStream(pathname)) {
			System.out.println(pathname + "파일 내용...");
			while ( (data = fis.read()) != -1) {
				System.out.write(data);
			}
			System.out.flush();
		} catch (FileNotFoundException e) {
			System.out.println(pathname+"은/는 존재하지 않는 파일 입니다.");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

FileInputStream(String name) 주어진 이름의 파일을 바이트 스트림으로 읽기 위한 FileInputStream 객체를 생성하는 메소드.

2021.08.24 - [쌍용강북교육센터/8월] - 0823_Java : FileOutStream 클래스 에서 저장한 파일을 읽어와 보았다.

FileOutStream 클래스

- 데이터를 파일 시스템의 파일에 바이트 스트림으로 저장하기 위해 사용된다.

- OutputStream(바이트 스트림) 클래스의 하위 클래스

- 기본적으로 파일이 없으면 생성하고, 이미 존재하면 그 파일에 덮어 씀으로 기존 내용은 사라진다.

 

import java.io.FileOutputStream;
import java.io.IOException;

public class Ex11_FileOutputStream {

	public static void main(String[] args) {
		String pathname = "test.txt";
		// 파일에 내용을 저장하는 byte 스트림
		FileOutputStream fos = null; // 메모리할당을 받지 않음.
		// 쓰레기를 가지고 있음.
		// 초기화되어있지 않아서. ex; int a; 
		int data;
		
		try { // 이 블록은 무조건 실행하는 것은 아님
			fos = new FileOutputStream(pathname); // 메모리할당받음
				// 해당 파일이 없으면 생성하고, 존재하면 삭제하고 만듦.
			System.out.println("문자열 입력[Ctrl+Z:종료]");
			while( (data = System.in.read()) != -1) {
				fos.write(data);
			}
			fos.flush();
			System.out.println("파일 저장 완료...");
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(fos != null) { // 메모리할당되어있으면 닫아야함.
				try {
					fos.close(); // 리소스를 닫아주어야 에러가 생기지 않음.
				} catch (Exception e2) {
				}
			}
		}
		
	}

}

위와 같은 의미

import java.io.FileOutputStream;
import java.io.IOException;

public class Ex12_FileOutputStream {

	public static void main(String[] args) {
		String pathname = "test.txt";
		int data;
		
		// JDK 7.0부터 가능 자동 close
		try (FileOutputStream fos = new FileOutputStream(pathname)) {
			System.out.println("문자열 입력[종료:ctrl+z]");
			
			while( (data = System.in.read()) != -1) {
				fos.write(data);
			}
			fos.flush();
			System.out.println("파일 저장 완료...");
		} catch (IOException e) {
			// ctrl+shift+o : 자동 import
			e.printStackTrace();
		}

	}

}

try( 리소스 객체 생성) 하게 되면 자동으로 close 해주기 때문에 따로 finally 에서 문자열입력을 받았으면 (객체가 생성되었으면) 닫는 부분의 코딩을 안해도된다.

키보드로 입력한 값을 1byte씩 읽고 1byte씩 파일에 넣기 때문에 문자가 잘 들어가진다.

 

FileOutputStream(String name) 주어진 이름의 파일을 바이트 스트림으로 쓰기 위한 FileOutputStream객체를 생성한다. 

 

BufferedReader 는 문자 입력 스트림을 처리하는 클래스이다.

버퍼를 활용하여 입력 속도를 향상시키고 한줄씩 입력이 가능하다.

]

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Ex10_BufferedReader {

	public static void main(String[] args) {
		// BufferedReader : 문자 입력 스트림
		// 	 버퍼를 활용하여 입력 속도 향상
		// 	 한줄씩 입력 가능
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		try {
			String name, s;
			int age;
			
			System.out.print("이름 ? ");
			name = br.readLine();
			
			System.out.print("나이 ? ");
			age = Integer.parseInt(br.readLine());
			
			s = age >= 19 ? "성인" : "미성년자";
			
			System.out.println(name+ "님은 " + s + "입니다.");
			
		} catch (NumberFormatException e) { // unchecked 예외
			System.out.println("나이는 숫자만 입력 가능합니다.");
		} catch (IOException e) {
			e.printStackTrace();
		} 
		
	}

}

BufferedReader가 문자 입력 스트림을 처리하기 때문에 문자 입력 스트림인 InputStreamReader의 객체생성을 통해 객체를 만듦.

 

age 의 경우 readLine을 통해 입력 받은 String을 int형으로 변환해서 넣어준다.

 

한 줄씩 처리하기 때문에 훨씬 입력 속도가 향상된다.

문자 스트림 

- 2바이트(16bit)의 유니코드(Unicode) 문자를 입출력하기위한 스트림이다.

- 문자 단위로 입출력을 수행한다.

- 모든 문자 스트림 클래스는 Reader 및 Writer 클래스의 서브 클래스이다.

Bridge Stream

- 1byte stream을 2byte stream으로 변환해주는 stream이다.

- Bridge Stream에는 InputStreamReader 와 OutputStreamWriter 클래스가 있다.

 

Reader 클래스는 문자 입력을 위한 추상 클래스로, 모든 문자 입력 스트림의 최상위 클래스이다.

import java.io.InputStreamReader;
import java.io.Reader;

public class Ex08_Reader {

	public static void main(String[] args) {
		int data;
		char ch;
/*
 		Reader : 문자 입력 스트림. 추상 클래스 
 		InputStreamReader : byte 스트림을 문자 스트림으로 변환(bridge stream)
 */
		
		try {
			Reader rd = new InputStreamReader(System.in);
			
			// "ABC엔터" 입력 : 65 66 67 13 10
			// "대한엔터" 입력 : 45824 54620 13 10
			// 영어 한글 모두 한번에 한문자씩 입력
			
			
			System.out.println("입력[ctrl+z:종료]");
			while( (data = rd.read()) != -1) {
				// System.out.println(data);
				ch = (char) data;
				// System.out.write(ch);
					// 한글깨짐. 2byte 문자를 1byte만 출력하므로 
				System.out.print(ch);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

문자 스트림을 입출력하기 위한 Bridge Stream 인 InputStreamReader를 추상 클래스인 Reader 로 업캐스팅 함. read() 입력한 값이 없을때까지 출력. ( -1 이 파일 끝 더이상 읽을 것이 없을때의 값)

 다른 포스팅에서는 read()가 1바이트씩 읽는 메소드였으나 (InputStream과 OutputStream에서는 바이트 스트림이기 때문에 1바이트만 읽음) 하지만 문자 스트림에서는 (Reader) 단일 문자를 읽으므로 2바이트를 읽는다. 따라서 2바이트를 data에 넘겨주고, ch로 강제 형변환 하고 write(ch)로 출력하면 한글은 2바이트 이기 때문에 깨진다.

대한 을 입력하면 문자 '대'를 data에 넘겨주고 그 대에 해당하는 ASCII 코드 값이 ch에 저장되고 ch(2바이트)를 출력할 때 write() 메소드는 1byte만 출력하므로 깨져서 나온다.

 

따라서 print(ch); 메소드로 출력해야 한다. 

PrintStream

- System.out은 PrintStream의 객체이다.

- 다른 출력 스트림의 기능을 추가하여 다양한 데이터 값의 표현을 편리하게 출력한다.

- 다른 출력 스트림과는 다르게 IOException이 발생하지 않는다.

- 자동으로 flush()가 되도록 생성할 수 있다. 자동으로 플래시 되는 경우, println() 메소드나 개행 문자, 또는 byte(\n)에 의해 자동으로 flush() 메소드가 호출된다.

- 인코딩을 설정하지 않으면 디폴트 문자 인코딩을 사용해 바이트로 변환한다.

- OutputStream, FilterOutputStream 클래스의 하위 클래스이다.

public class Ex07_PrintStream_write {

	public static void main(String[] args) {
		// System.out : PrintStream 객체
		// PrintStream : 다양한 출력이 가능한 출력 스트림(필터 스트림)
		//		IOException이 발생되지 않음.

		System.out.write(65); // 하위 1byte를 출력 버퍼로 보냄
		System.out.write(65);
		System.out.write(65);
		
		System.out.flush(); // 출력 버퍼의 내용을 출력 장치로 보냄
	}

}

InputStream과 OutputStream은 checked Exception이 존재하기 때문에 try ~ catch 를 사용해야 에러가 뜨지 않았지만, PrintStream은 try ~ catch 없이 사용이 가능하다.


import java.io.PrintStream;

/*
 - PrintStream 클래스
   System.out은 PrintStream 객체
   다른 출력 스트림의 기능을 추가하여 다양한 데이터 값의 표현을 편리하게 출력
   IOException 발생하지 않는다. 
   자동으로 flush()가 되도록 생성할 수 있다.
   
 */
public class Ex010_PrintStream {
	public static void main(String[] args) {
		String name = "홍길동";
		int kor = 80;
		int eng = 90;
		int mat = 100;

		// String => byte[]
		// byte[] b = name.getBytes();
		
		try (PrintStream ps = new PrintStream("test.txt")) {
			// ps.println(name+"\t"+kor+"\t"+eng+"\t"+mat);
			// ps.printf("%10s %5d %5d %5d",  name, kor, eng, mat);
			
			ps.print("이름:"+name+",");
			ps.print(kor+",");
			ps.print(eng+",");
			ps.print(mat);
			
			System.out.println("파일 저장 완료");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

문자와 숫자가 모두 섞여 있지만 (String, int) PrintStream을 통해서 편리하게 출력할 수 있다.

test.txt 에 출력하라는 의미. 실행 후

test.txt 파일이 만들어지고 그 안에 출력되었음을 알 수 있다.

 


PrintWriter 클래스

- PrintWriter 클래스는 포맷된 오브젝트의 표현을 텍스트 출력 스트림에 출력한다.

- PrintStream에 있는 print메소드가 모두 구현되어 있다. 단, 인코딩 되지 않은 바이트 스트림을 사용해야하는 메소드는 포함되어 있지 않다.

- 일부분의 생성자를 제외하고는 예외를 throws 하지 않는다.

- PrintStream 클래스와 다르게 자동 플러시(autoFlush) 활성화된 경우 개행 문자를 출력할 때가 아닌, println(), printf(), format() 메소드가 호출될 때만 자동 플러시된다. print() 메소드 등은 flush() 가 호출되거나 PrintWriter객체가 close()될 때 수행된다.

- Writer 클래스의 하위 클래스이다.

import java.io.PrintWriter;

// PrintWriter : 바이트가 아닌 문자를 출력할 때 사용
public class Ex013_PrintWriter {

	public static void main(String[] args) {
		// PrintStream -> PrintWriter
/*		
		PrintWriter pw = new PrintWriter(System.out);
		pw.print("자바");
		pw.print("오라클");
		pw.println("web");
		pw.flush(); // flush()를 호출하거나 close()해야 출력
*/
		
		// true 옵션을 주면 flush()를 호출하거나 println()을 호출하면 출력
		PrintWriter pw = new PrintWriter(System.out, true);
		pw.print("자바");
		pw.print("오라클");
		pw.println("web");
		
		
		
	}

}

 

'쌍용강북교육센터 > 8월' 카테고리의 다른 글

0823_Java : Writer 클래스  (0) 2021.08.24
0823_Java : Reader 클래스  (0) 2021.08.23
0823_Java : OutputStream 클래스  (0) 2021.08.23
0823_Java : InputStream 클래스  (0) 2021.08.23
0820_Oracle[PL/SQL] : 예외처리  (0) 2021.08.23

OutputStream 클래스는 추상 클래스로 모든 바이트 출력 스트림의 최상위 클래스이다.

 

import java.io.OutputStream;

public class Ex05_OutputStream {

	public static void main(String[] args) {
		int data = 97;
		byte [] b = {65, 66, 67, 68, 69, 70};

		try {
			OutputStream os = System.out;
				// OutputStream : 출력 byte 스트림
			
			os.write(data); // 하위 1byte 출력
			System.out.println();
			
			os.write(b); // byte 배열 출력. ABCDEF
			System.out.println();
			
			os.write(b, 2, 3); // CDE. 2번째 인덱스에서 3개 출력
			System.out.println();
			
			System.out.write(b, 0, b.length); // off 인덱스로부터 len 개를 출력 장치로
			System.out.println();
			
			os.close();
			
			System.out.println("end..."); // 출력 안됨
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

os.write(data); 에서 data는 int형(4바이트) 이므로 1바이트씩 읽고 넘겨준다. 하위 1byte를 출력하는데 숫자 97를 문자로 읽어들이고 그 바이트값을 넘기면 ASCII코드의 97를 출력하게 된다. (a)

write(b); 에서 byte 배열인 B를 출력하면 1byte의 문자를 읽어들여 ASCII 코드 값을 반환하므로 ABCDEF.

 

OutputStream의 객체인 os 를 닫으면 close(); 마지막 end...는 출력되지 않는다. close()하면 바이트 입력 스트림을 닫고 사용하고 있던 시스템 자원들을 모두 반환한다.


import java.io.OutputStream;

public class Ex06_OutputStream {

	public static void main(String[] args) {
		try {
			OutputStream os = System.out;
			
			os.write(65); // 하위 1byte출력
						// 출력 버퍼에 출력되며 출력 버퍼가 차지 않으면 
						// 실제 출력 장치로 보내지 않음
			os.write(67);
			os.write(68);
			
			// 위내용 출력 방법
			// 1) 첫번째 방법
			os.flush(); // 출력 버퍼의 내용을 출력 장치로 보냄
			
			// 2) 두번째 방법
			// os.write(13);
			// os.write(10); // 이것만 해도 가능
			
			// 3) 세번째 방법
			// System.out.println(); // 위의 내용이 출력됨
			
			// 4) 네번째 방법
			// os.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

write(); 에 넣어준 문자는 바로 출력되지 않고 출력 버퍼에 저장되었다가 출력 버퍼가 차면 출력 장치로 보내준다.

따라서 출력 버퍼의 내용을 출력 장치로 보내는 flush() 메소드를 통해 모아뒀다가 출력할 수 있다.

 

두 번째 방법은 엔터(ASCII로 2byte)의 ASCII 값을 직접 입력 한 것이고, 세 번째 방법도 2번째와 비슷한 방식이다. 네 번째 방법은 바이트 입력 스트림을 닫고 자원을 반환하며 출력된다.

바이트 스트림 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