본문 바로가기
Programming Language/Java

[국비] Java 내용정리 Day18

by tpleehan 2021. 12. 1.

음식점 메뉴판 관리 프로그램

package collection.map;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class FoodManager {

	public static void main(String[] args) {

		Map<String, Integer> foods = new HashMap<>();
		
		Scanner sc = new Scanner(System.in);
		
		System.out.println("*** 음식점 메뉴판 관리 프로그램 ***");
		
		while (true) {
			
			System.out.println("# 1. 메뉴 등록");
			System.out.println("# 2. 메뉴 전체보기");
			System.out.println("# 3. 프로그램 종료");
			System.out.print("> ");
			int menu = sc.nextInt();
			
			System.out.println("-------------------------------------");
			
			if (menu == 1) {
				System.out.println("등록할 메뉴를 입력하세요.");
				System.out.print("> ");
				String food = sc.next();
				if (foods.containsKey(food)) {
					System.out.println(food + "(은)는 이미 존재하는 메뉴입니다.");
					continue;
				} else {
					System.out.print("등록할 음식의 가격: ");
					int price = sc.nextInt();
					
					foods.put(food, price);
					System.out.printf("%s 음식이 등록 되었습니다.\n", food);
					
				}
				
			} else if (menu == 2) {

				if (foods.isEmpty()) {
					System.out.println("메뉴부터 먼저 등록해주세요.");
				} else {
					System.out.println("---------- 메뉴판 ----------");
					
					for (String m : foods.keySet()) {
						System.out.println(m + " : " + foods.get(m));
					}
					System.out.println("---------------------------\n");
					
					System.out.println("1. 수정 | 2. 삭제 | 3. 취소");
					System.out.print("> ");
					int sel = sc.nextInt();
					
					switch (sel) {
					case 1:
						System.out.print("수정할 메뉴: ");
						String cMenu = sc.next();
						if (foods.containsKey(cMenu)) {
							System.out.print("수정할 가격: ");
							int newPrice = sc.nextInt();
							foods.put(cMenu, newPrice);
							System.out.printf("%s 음식이 %d원으로 수정되었습니다.\n", cMenu, newPrice);
							
						} else {
							System.out.println(cMenu + "은(는) 존재하지 않는 메뉴 입니다.");
						}
						break;
						
					case 2:
						System.out.print("삭제할 메뉴: ");
						String del = sc.next();
						if (foods.containsKey(del)) {
							foods.remove(del);
							System.out.println(del + "이(가) " + "삭제 되었습니다.");
						} else {
							System.out.println(del + "은(는) 존재하지 않는 음식 입니다.");
						}
						
					case 3:
						System.out.print("메인 메뉴로 이동합니다.\n");
						break;

					default:
						System.out.println("메뉴를 잘못 입력했습니다.");
						System.out.println("메인 메뉴로 돌아갑니다.");
						
					}
				}
			} else if (menu == 3) {

				System.out.println("프로그램을 종료하시겠습니까? [Y / N]");
				System.out.print("> ");
				String quit = sc.next();
				if (quit.toLowerCase().equals("y") || quit.equals("ㅛ")) {
					System.out.println("프로그램이 정상 종료 되었습니다.");
					sc.close();
					System.exit(0);
					
				} else {
					System.out.println("종료를 취소합니다.");
					
				}
				
			} else {
				System.out.println("메뉴를 잘못 입력했습니다.");
				
			}
			
		}
		
	}

}

API - IO(Input 스트림 - Output 스트림)

Stream

  • 스트림은 데이터의 흐름(흐르는 통로)를 말한다.
    • 데이터가 들어오면 입력 스트림이다.
    • 데이터가 나가면 출력 스트림이다.
    • 스트림 클래스는 크게 두 종류로 구분된다.
      • byte기반
        • 그림, 문자 등 모든 종류의 데이터를 보낼 수 있다.
      • 문자 기반
        • 오직 문자만 보낼 수 있도록 특화 되어 있다.

OutputStream 클래스

  • OutputStream은 바이트 기반 출력 스트림의 최상위 클래스로 추상 클래스이다.

OutputStream 주요 메서드

  1. write(byte b)
    • 출력 스트림으로 1바이트를 내보낸다.
  2. write(byte[] b)
    • 출력 스트림으로 주어진 바이트 배열 b의 모든 바이트들을 내보낸다.

InputStream 클래스

  • InputStream 클래스는 바이트 기반 입력 스트림의 최상위 클래스로 추상 클래스이다.

InputStream 사용방법

  • InputStream (추상)클래스를 이용해서 객체를 만든다. 하위 클래스로 구현 시킨다.
  • 한글의 경우 2바이트로 한글이 깨지는 현상이 발생한다.

InputStream 주요 메서드

  1. read()
    • 입력 스트림으로부터 1바이트를 읽고 읽은 바이트를 리턴하낟.
  2. read(byte[] b)
    • 입력 스트림으로부터 읽은 바이트들을 매개 값으로 주어진 바이트 배열에 저장하고 실제로 읽은 바이트 수를 리턴한다.
  3. close()
    • 스트림을 더 이상 사용하지 않을 경우 사용한 시스템 자원을 풀어준다.

package api.io.stream;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;

public class InputStreamEx {

	public static void main(String[] args) {

		FileInputStream fis = null;
		try {
			fis = new FileInputStream("C:\\java\\Day18\\file\\test.txt");
			
			/*
			while (true) {
				int data = fis.read(); // 1바이트 단위로 데이터를 읽어온다.
				System.out.print((char) data); // 숫자형을 문자형으로 변환 출력
				
				// read() 메서드가 더 이상 읽을 값이 없다면 -1을 반환
				if (data == -1) {
					break; 
				}
				
			}
			 */
			
			byte[] arr = new byte[100];
			int result = fis.read(arr); // 100바이트 단위로 읽어들인다.
			System.out.println("읽어들인 데이터 길이: " + result);
			System.out.println(Arrays.toString(arr));
			
			int i = 0;
			while (arr[i] != 0) {
				System.out.print((char) arr[i]);
				i++;
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			
		} finally {
			try {
				// 스트림을 더 이상 사용하지 않을 경우
				// 시스템 자원을 반납하는 코드를 꼭 작성한다.
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
		
	}
	
}
  • 파일을 읽어 들이는 데 사용하는 클래스는 FileInputStream
  • 생성자의 매개값으로 읽어들일 파일의 전체 경로를 적는다.
  • InputStream 객체는 생성자에 throws가 있기 때문에 try - catch 안에서 사용한다.
package api.io.stream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class OutputStreamEx {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.print("파일명: ");
		String name = sc.next();
		
		FileOutputStream fos = null;
		
		try {
			fos = new FileOutputStream("C:\\java\\Day18\\file\\" + name + ".txt");
			
			System.out.print("문장을 입력하세요: ");
			sc.nextLine();
			String str = sc.nextLine();
			
			byte[] arr = str.getBytes(); // 문자열 데이터를 byte 데이터로 변환해준다.
			
			fos.write(arr);  // 파일을 바이트 단위로 써 내린다.
			System.out.println("파일이 정상적으로 저장 되었습니다.");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fos.close();
				sc.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

}
  • 파일을 쓸 때 (작성) 사용하는 클래스는 FileOutputStream
  • 생성자의 매개값으로 파일을 쓸 전체 경로를 지정한다.
  • io패키지의 모든 클래스는 생성자에 throws 키워드가 있기 때문에 try-catch 블록을 항상 작성해야 한다.
package api.io.stream;

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

public class StreamCopy {

	public static void main(String[] args) {
		
		FileInputStream oldFile = null;
		FileOutputStream newFile = null;
		
		try {
			oldFile = new FileInputStream("C:\\java\\Day18\\image\\1.jpg");
			newFile = new FileOutputStream("C:\\java\\Day18\\image\\newImage\\copy.jpg");
			
			byte[] arr = new byte[100];
			
			while (true) {
				// 읽어들인 데이터가 있다면 읽은 데이터 길이 반환
				// 없다면 -1을 반환
				int result = oldFile.read(arr);
				if (result == -1) {
					break; // 탈출
					
				} else {
					// byte단위로 0 부터 읽은 크기까지의 파일을 작성
					newFile.write(arr, 0, result);					
				}				
			}			
		} catch (Exception e) {
			e.printStackTrace();			
		} finally {
			try {
				oldFile.close();
				newFile.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

File Quiz

1. 스캐너를 통해서 파일명을 정확히 입력받는다.
2. file폴더에 해당 파일이 존재한다면 해당 파일을 upload폴더로 복사한다.
    파일이 존재하지 않는다면 "파일명이 없습니다." 라고 예외구문을 출력
3. 복사 도중에 에러가 발생하면 "파일 처리 중 예외 발생!" 구문을 출력
package api.io.stream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class FileQuiz {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		FileInputStream  oldFile = null;
		FileOutputStream newFile = null;
		
		try {
			System.out.print("파일명을 입력하세요: ");
			String name = sc.next();
			
			oldFile = new FileInputStream("C:\\java\\Day18\\file\\" + name + ".txt");
			newFile = new FileOutputStream("C:\\java\\Day18\\upload\\" + name + ".txt");
			int result;
			byte[] arr = new byte[100];
			
			/*
			while ((result = oldFile.read(arr)) != -1) {
				newFile.write(arr, 0, result);
			}
			 */
			
			while (true) {
				result = oldFile.read(arr);
				if (result == -1) {
					break;
				} else {
					newFile.write(arr, 0, result);
				}
			}
			System.out.println("파일 복사를 완료 했습니다.");
			
		} catch (FileNotFoundException e) {
			System.out.println("해당 파일명을 찾을 수 없습니다.");
		} catch (IOException e){
			System.out.println("파일 처리 중 예외가 발생했습니다.");
		} finally {
			try {
				oldFile.close();
				newFile.close();
				sc.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
				
	}

}
package api.io.folder;

import java.io.File;

public class CreateFileEx {

	public static void main(String[] args) {

		File file = new File("C:\\java\\Day18\\file\\folder_test");
		
		if (!file.exists()) { // 해당 파일 및 폴더가 존재하면 true, 존재하지 않으면 false
			file.mkdir(); // 폴더 생성
			System.out.println("폴더 생성 완료");
		} else {
			System.out.println("해당 폴더가 존재합니다.");
		}
		
	}

}
  • 외부 경로로 폴더를 생성할 때는 File 클래스를 사용한다.
  • .exists() 메서드는 해당 경로에 폴더가 있는지 확인해준다.
  • 생성자의 매개값으로 폴더를 생성할 경로 + 폴더명을 지정한다.
package api.io.folder;

import java.io.File;

public class DeleteFileEx {

	public static void main(String[] args) {
		
		File file = new File("C:\\java\\Day18\\file\\folder_test");
		
		if (file.exists()) { 
			file.delete(); // delete 성공 시 true, 실패 시 false를 리턴
			System.out.println("폴더 삭제 완료");
		} else {
			System.out.println("해당 폴더 삭제 실패 or 해당 폴더가 존재 하지않습니다.");
		}
		
	}

}

문자 기반 스트림 클래스

  • Input/OutputStream은 1바이트 단위로 입/출력 동작을 수행하지만 한글의 경우 2바이트이기 때문에 바이트 단위 처리시 글자가 깨질 수 있다.
  • 해당 문제점을 없애기 위해 문자나 문자열을 다룰 때 유니코드 방식을 제공한다.
  • 유니코드를 사용하는 입/출력 클래스는 Reader와 Writer라고 부르며, 사용시 자동으로 바이트가 유니코드화 되기 때문에 한글 같은 2바이트 문자도 정상적으로 처리할 수 있다.

Writer / Reader 클래스

  • 텍스트 파일을 프로그램으로 쓸 때 사용하는 문자 기반 스트림 클래스이다.

Writer / Reader 사용법

  • writer / reader (추상)클래스를 이용해서 객체를 만든다. 하위 클래스로 구현 시킨다.
  • 2바이트 문자도 정상적으로 처리할 수 있다.

Writer 주요 메서드

  • Stream의 Input/OutputStream 클래스를 제공하는 것처럼 Reader와 Writer를 FileReader/Writer가 제공해서 사용된다.
package api.io.rw;

import java.io.FileWriter;
import java.io.IOException;

public class FileWriterEx {

	public static void main(String[] args) {
		
		FileWriter fw = null;
		
		try {
			fw = new FileWriter("C:\\java\\Day18\\file\\hello.txt");
			
			// \r: 캐리지 리턴 -> 커서를 맨 앞으로 땡기는 동작
			// \n: 줄 개행 (줄바꿈)
			// 상황과 환경에 따라 줄 개행 시 커서를 맨 앞으로 안 땡겨주는 경우가 있다.
			String str = "오늘은 11월 11일 입니다.\r\n목요일 입니다.\r\n모두 즐거운 하루 되세요.";
			fw.write(str);
			
			System.out.println("파일이 정상적으로 저장 되었습니다.");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

}
package api.io.rw;

import java.io.FileReader;
import java.io.IOException;

public class FileReaderEx {

	public static void main(String[] args) {

		FileReader fr = null;
		
		try {
			fr = new FileReader("C:\\java\\Day18\\file\\hello.txt");
			
			char[] arr = new char[100];
			
			int result = fr.read(arr); // 문자를 하나씩 읽어들임
			System.out.println("문자의 개수: " + result);
			
			for (char c : arr) {
				System.out.print(c);
				if (c == 0) {
					break;
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

}

입출력 성능향상 스트림 BufferedWriter

BufferedWriter

  • 텍스트 파일을 프로그램으로 읽을 때 사용하는 문자 기반 스트림이다.
  • 데이터를 읽고 버퍼에 저장한 후 한번에 쓰는 형태로 사용되기 때문에 속도가 빠르다.

BufferedWriter 사용법

  • 생성자의 매개변수(문자출력스트림 클래스)를 전달한다.

BufferedWriter 주요 메서드

  • Writer 클래스와 거의 동일하다.
  • flush(): 버퍼를 비운다.

주의할 점

  • 버퍼가 가득찼을 때만 출력하기 때문에 flush()를 호출해서 잔류 데이터를 모두 제거해야 한다.
package api.io.buffered;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

public class BufferedWriterEx {

	public static void main(String[] args) {		
		Scanner sc = new Scanner(System.in);
		FileWriter fw = null;
		BufferedWriter bw = null;
		
		try {
			fw = new FileWriter("C:\\java\\Day18\\file\\test2.txt");
			bw = new BufferedWriter(fw);
			
			System.out.print("첫번 째 문장: ");
			String str1 = sc.nextLine();
			
			System.out.print("두번 째 문장: ");
			String str2 = sc.nextLine();
			
			bw.write(str1 + "\r\n" + str2);
			System.out.println("파일 정상 출력 완료");			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				bw.close();
				fw.close();
				sc.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
		
	}

}
package api.io.buffered;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderEx {

	public static void main(String[] args) {
		
		FileReader fr = null;
		BufferedReader br = null;
		
		try {
			fr = new FileReader("C:\\java\\Day18\\file\\test2.txt");
			br = new BufferedReader(fr);
			
			// BufferedReader에는 readLine() 메서드가 있고
			// 한 줄을 통째로  읽어서 String으로 리턴한다.
//			System.out.println(br.readLine());
//			System.out.println(br.readLine());
//			System.out.println(br.readLine());
			
			String str;
			while ((str = br.readLine()) != null) {
				System.out.println(str);
			}			
		} catch (Exception e) {
			e.printStackTrace();			
		} finally {
			try {
				br.close();
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

}
package api.io.buffered;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class BufferedInputStreamEx {

	public static void main(String[] args) {
		
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		
		try {
			fis = new FileInputStream("C:\\java\\Day18\\file\\test.txt");
			bis = new BufferedInputStream(fis);

			int b;
			while ((b = bis.read()) != -1) {
				System.out.print((char) b);
			}			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				bis.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
				
	}

}
package api.io.buffered;

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

public class BufferedOuputStreamEx {

	public static void main(String[] args) {

		// dummy data
		StringBuilder text = new StringBuilder();
		
		for (int i = 1; i <= 1000000; i++) {
			text.append(i + "안녕하세요.\n");			
		}
		
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;
			
		long start = System.currentTimeMillis();
		
		try {
			fos = new FileOutputStream("C:\\java\\Day18\\file\\bout.txt");
			bos = new BufferedOutputStream(fos);
			
			byte[] data = new String(text).getBytes();
			
			for (byte b : data) {
				bos.write(b);
			}			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				bos.close();
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		long end = System.currentTimeMillis();
		
		System.out.println("소요 시간 : " + (end - start) * 0.001 + "초");		
	}

}

Buffered Quiz01

1. Date클래스와 SimpleDateFormat클래스를 활용하여 file 경로에 20211111.txt이름으로 파일을 쓴다.
2. 내용은 아무거나 작성해도 무방하다.
3. 파일을 정상적으로 썼다면 BufferedReader를 통해 파일을 읽어들인다.

package api.io.buffered;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class BufferedQuiz {

	public static void main(String[] args) {

		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String today = sdf.format(date);

		String str = "안녕하세요. 반갑습니다. \n오늘은" +  today + "입니다. \n오늘의 날씨가 춥기 때문에 감기를 조심하세요. \n즐거운 하루 되세요.";
		
		FileWriter fw = null;
		BufferedWriter bw = null;	
		
		try {
			fw = new FileWriter("C:\\java\\Day18\\file\\" + today + ".txt");
			bw = new BufferedWriter(fw);
			
			bw.write(str);			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				bw.close();
				fw.close();
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		/////////////////////////// 파일 읽기 ///////////////////////////
		
		FileReader fr = null;
		BufferedReader br = null;
		
		try {
			fr = new FileReader("C:\\java\\Day18\\file\\" + today + ".txt");
			br = new BufferedReader(fr);
			
			String read;
			
			while ((read = br.readLine()) != null) {
				System.out.println(read);
			}			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}			
		}
		
	}
}

Buffered Quiz02

1. Date클래스를 이용해서 file폴더 내에 하위 경로로 오늘 날짜 20211111file 이라는 이름으로 폴더를 생성한다.
2. 스캐너로 파일명을 입력받고 파일명.txt로 파일을 쓴다.
3. '그만'이라고 입력할 때까지 엔터를 포함해서 실시간으로 파일을 작성한다.
package api.io.buffered;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class BufferedQuiz2 {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);

		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String today = sdf.format(date);

		File file = new File("C:\\java\\Day18\\file\\" + today + "file");
		
		if (!file.exists()) {
			file.mkdir();
			System.out.println("폴더가 생성되었습니다.");
		} else {
			System.out.println("폴더가 이미 존재합니다.");
		}
		
		BufferedWriter bw = null;
		String str = null;
		
		System.out.print("파일명을 입력하세요.: ");
		str = sc.nextLine();
		
		try {
			bw = new BufferedWriter(new FileWriter("C:\\java\\Day18\\file\\" + today + "file\\" + str + ".txt"));
			System.out.println("'그만'을 입력하면 중지합니다.");
			
			while (true) {
				System.out.print("입력할 내용: ");
				String text = sc.nextLine();
				
				if (text.equals("그만")) {
					System.out.println("종료합니다.");
					break;
				}
				
				text += "\r\n";
				bw.write(text);
				bw.flush(); // 버퍼가 가득차지 않아도 문자열을 파일로 내보내는 메서드						
			}			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		/////////////////////////// 파일 읽기 ///////////////////////////
		
		FileReader fr = null;
		BufferedReader br = null;
		
		try {
			fr = new FileReader("C:\\java\\Day18\\file\\" + today + "file\\" + str + ".txt");
			br = new BufferedReader(fr);
			
			String read;
			
			while ((read = br.readLine()) != null) {
				System.out.println(read);
			}			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}			
		}
		
	}
}​

 

'Programming Language > Java' 카테고리의 다른 글

[국비] Java 내용정리 Day20  (0) 2021.12.04
[국비] Java 내용정리 Day19  (0) 2021.12.02
[국비] Java 내용정리 Day17  (0) 2021.11.29
[국비] Java 내용정리 Day16  (0) 2021.11.28
[국비] Java 내용정리 Day15  (0) 2021.11.25

댓글