24일차 과제 클래스로 구현해보기
package api.collection3;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class RentApp {
private Map<String, Car> map = new HashMap<>();
private Scanner sc = new Scanner(System.in);
public RentApp() {
// 데이터 추가
map.put("스타렉스", new Car("스타렉스", 11, 150000));
map.put("카니발", new Car("카니발", 7, 170000));
map.put("그랜저", new Car("그랜저", 4, 200000));
}
public String menu() {// 메뉴
System.out.println("<렌트카>");
System.out.println("저희 렌트카는 항상 친절과 정성으로 고객을 모시겠습니다~");
System.out.println("원하시는 명령을 입력해주세요");
System.out.println("- 대여");
System.out.println("- 반납");
System.out.println("- 종료");
System.out.print("명령 입력 : ");
String command = sc.nextLine();
return command;
}
public void exit() {// 종료
System.out.println("프로그램을 종료합니다");
sc.close();
System.exit(0);
}
public void rental() {// 대여
System.out.print("차량명 입력 : ");
String name = sc.nextLine();
if (map.containsKey(name)) {
Car find = map.get(name);
if (find.isRent()) {
System.out.println("대여 가능한 차량입니다");
find.rental();// find.setRent(false);//대여 처리
System.out.println("대여 처리가 완료되었습니다");
} else {
System.out.println("대여중인 차량입니다");
}
} else {
System.out.println("차량이 존재하지 않습니다");
}
}
public void rentalReturn() {// 반납
System.out.print("차량명 입력 : ");
String name = sc.nextLine();
if (map.containsKey(name)) {
Car find = map.get(name);
if (!find.isRent()) {
System.out.println("반납 가능한 차량입니다");
find.setRent(true);// 반납 처리
System.out.println("반납 처리가 완료되었습니다");
} else {
System.out.println("대여중인 차량이 아닙니다");
}
} else {
System.out.println("차량이 존재하지 않습니다");
}
}
public void information() {
System.out.println("잘못 입력하셨습니다");
}
public void action(String command) {
// if(command.equals("종료")) {
// this.exit();
// }
// else if(command.equals("대여")) {
// this.rental();
// }
// else if(command.equals("반납")) {
// this.rentalReturn();
// }
// else {
// this.information();
// }
switch (command) {
case "종료":
this.exit();
break;
case "대여":
this.rental();
break;
case "반납":
this.rentalReturn();
break;
default:
this.information();
break;
}
}
public void run() {
while (true) {
try {
String command = this.menu();
this.action(command);
} catch (Exception e) {
e.printStackTrace();
System.out.println("오류 발생. 관리자에게 문의하세요");
}
}
}
}
package api.collection3;
public class Test05_9 {
public static void main(String[] args) {
RentApp app = new RentApp();
app.run();
}
}
Collection - Map iteration
Q : Map이 개별 저장소인건 알겠는데... 전체 목록 출력은 아예 안되는건가?
A : 되긴 되는데... map에서 key 목록을 추출하는 명령이 필요하다.
Map에서 Key 만 뽑아서 생각해보면 Set 형태를 띈다고 볼 수 있다.
keySet() 명령을 사용하면 반환형이 Set이다.
key를 모두 열거한 다음 연결된 value를 불러오면 모든 데이터를 조회할 수 있다.
package api.collection3;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class Test06_1 {
public static void main(String[] args) {
// Map<String, Integer> map = new HashMap<>();
Map<String, Integer> map = new TreeMap<>();
map.put("피카츄", 75);
map.put("라이츄", 65);
map.put("파이리", 90);
Set<String> set = map.keySet();
for (String name : set) {
System.out.println("name = " + name);
System.out.println("score = " + map.get(name));
}
}
}
Collection - Stack, Queue
Stack과 Queue
Queue : 대기열. 줄을 서서 기다리는 형태. FIFO(선입선출) 구조
Stack : 출입구가 하나뿐인 저장소 형태. LIFO(후입선출) 구조
이러한 저장소들은 사용법이 정해져 있으므로 그 이외의 사용이 불가
package api.collection4;
import java.util.Stack;
public class Test01 {
public static void main(String[] args) {
Stack<String> st = new Stack<>();
st.push("아이유");
st.push("공유");
st.push("이동욱");
st.push("한지민");
st.push("전지현");
while(!st.empty()) {
System.out.println(st.pop());
}
}
}
전지현
한지민
이동욱
공유
아이유
Stack 형식의 저장소를 사용하면 "이력 관리"를 할 수 있다.
되돌리기 명령 실행 시 pop() 을 통하여 나온 데이터를 이용하여 어떤 처리를 수행할 수 있다
package api.collection4;
import java.util.Stack;
public class Test02 {
public static void main(String[] args) {
Stack<String> history = new Stack<>();
history.push("https://www.google.com");
history.push("https://www.naver.com");
history.push("https://www.daum.net");
System.out.println(history.pop());
System.out.println(history.pop());
System.out.println(history.pop());
}
}
https://www.daum.net
https://www.naver.com
https://www.google.com
Queue : FIFO(선입선출) 저장소
등록한 순서대로 추출이 가능하므로 작업 순서등을 설정할 때 유리
package api.collection4;
import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
public class Test03 {
public static void main(String[] args) {
Queue<String> q = new ArrayBlockingQueue<>(10);
q.add("아이유");
q.add("공유");
q.add("이동욱");
q.add("한지민");
q.add("전지현");
System.out.println(q.peek());// 조회(누가 나올 차례인가요?)
System.out.println(q);// 데이터 변화 없음
System.out.println(q.poll());// 추출(나오세요!)
System.out.println(q);// 데이터 사라짐
System.out.println(q.poll());
System.out.println(q.poll());
System.out.println(q.poll());
System.out.println(q.poll());
System.out.println(q.poll());
System.out.println(q.poll());
System.out.println(q.poll());
System.out.println(q);
}
}
파일 - File 제어
파일(File)이란?
글자를 보관하기 위한 저장공간
파일의 크기 == 파일 안에 들어있는 글자의 크기
1. 일반적인 글자를 보관하기 위한 파일(텍스트 파일)
2. 특정 프로그램에서만 이해할 수 있는 파일(바이너리 파일)
File 클래스에서는 물리 저장소에 존재하는 파일을 제어할 수 있다.
해당하는 파일의 객체를 생성해야 제어가 가능하며, 생성을 위해서는 반드시 정보가 필요하다.
필요한 정보 : 파일이 위치한 경로와 파일의 이름
자바에서는 전체경로를 적지 않으면 프로젝트부터 계산한다
package api.io.file;
import java.io.File;
public class Test01 {
public static void main(String[] args) {
File a = new File("sample", "test.txt");//sample 폴더의 test.txt 관리 객체 생성!
File b = new File("sample/test.txt");//sample/test.txt 관리 객체 생성!
File c = new File("sample\\test.txt");//sample\test.txt 관리 객체 생성!
//올바른 파일을 대상으로 생성하였는지 검사
System.out.println(a.exists());//a의 대상 파일이 존재하는가?
System.out.println(b.exists());//b의 대상 파일이 존재하는가?
System.out.println(c.exists());//c의 대상 파일이 존재하는가?
}
}
파일 정보 분석
package api.io.file;
import java.io.File;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test02 {
public static void main(String[] args) {
File f = new File("sample", "test.txt");
System.out.println(f.exists());
// 1. 파일명
System.out.println(f.getName());
// 2. 파일 위치(경로)
// = 상대 경로란 특정 지점을 기준으로 계산한 경로를 의미한다(우리 옆집)
// = 절대 경로란 어떠한 경우에도 변하지 않는 경로를 의미한다(집주소)
System.out.println(f.getPath());// 상대경로(relative path)
System.out.println(f.getAbsolutePath());// 절대경로(absolute path)
// 3. 파일 크기 : 반환형이 long임을 주의해야 한다
System.out.println(f.length());
// 4. 최종 수정 시각 : 최신 파일 여부를 판단할 때 사용
System.out.println(f.lastModified());
Date d = new Date(f.lastModified());
Format form = new SimpleDateFormat("yyyy-MM-dd E a h:mm:ss");
System.out.println(form.format(d));
// 5. 숨김 파일인지 확인
System.out.println(f.isHidden());
// 6. 읽기 전용인지 확인
System.out.println(f.canRead());
System.out.println(f.canWrite());
}
}
자바에서는 파일 뿐만 아니라 폴더(디렉터리, Directroy)도 File 클래스로 제어가능
디렉터리란? 파일을 보관하기 위한 틀(껍데기, 통)
디렉터리는 크기가 없다
package api.io.file;
import java.io.File;
public class Test03 {
public static void main(String[] args) {
File dir = new File("sample");
System.out.println(dir.exists());
// 정보 분석
// 1. 디렉터리는 크기가 없다.
System.out.println(dir.length());
// 2. 이름
System.out.println(dir.getName());
// 3. 경로
System.out.println(dir.getPath());
System.out.println(dir.getAbsolutePath());
// 4. 내부의 파일 목록
// = list() : 이름만 반환
// = listFiles() : 파일 객체를 반환
String[] names = dir.list();
for (String name : names) {
System.out.println(name);
}
File[] files = dir.listFiles();
for (File f : files) {
System.out.println(f);
System.out.println("file? " + f.isFile());
System.out.println("directory? " + f.isDirectory());
}
}
}
Q. 사용자에게 파일 또는 디렉터리의 경로를 입력받아 다음과 같이 처리하는 프로그램을 구현
1. 사용자가 입력한 경로가 `파일`인 경우 파일 정보 중 다음 내용을 출력
- 절대경로
- 파일 크기
- 최종 수정시각을 다음과 같이 출력(2021년 9월 14일 화 14시 53분 2초)
2. 사용자가 입력한 경로가 `디렉터리`인 경우 디렉터리 내부의 목록을 출력
- 내부 목록 중 파일은 이름 좌측에 [파일] 을 붙여서 출력
- 파일은 이름 우측에 크기를 붙여서 출력
- 내부 목록 중 디렉터리는 이름 좌측에 [폴더] 를 붙여서 출력
3. 사용자가 입력한 경로가 존재하지 않는 경로일 경우 다음 메세지를 출력
- 해당 경로는 존재하지 않습니다.
package api.io.file;
import java.io.File;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Test04_1 {
public static void main(String[] args) {
// 경로 입력
Scanner sc = new Scanner(System.in);
System.out.print("경로 입력 : ");
String path = sc.nextLine();
sc.close();
// 파일 객체 생성
File file = new File(path);
if (file.exists()) {// 존재하는 경우(파일 또는 디렉터리)
if (file.isFile()) {
System.out.println("[파일 정보]");
System.out.println("이름 : " + file.getName());
System.out.println("절대경로 : " + file.getAbsolutePath());
System.out.println("크기 : " + file.length() + " byte");
Format f = new SimpleDateFormat("y년 M월 d일 E h시 m분 s초");
Date d = new Date(file.lastModified());
System.out.println("최종 수정 시각 : " + f.format(d));
}
// else if(file.isDirectory()) {
else {
System.out.println("[디렉터리 정보]");
System.out.println("이름 : " + file.getName());
File[] files = file.listFiles();
for (File f : files) {
if (f.isFile()) {
System.out.println("--> [파일] " + f.getName() + " (" + f.length() + " bytes)");
} else if (f.isDirectory()) {
System.out.println("--> [폴더] " + f.getName());
}
}
}
} else {// 존재하지 않는 경우
System.out.println("해당 경로는 존재하지 않습니다.");
}
}
}
경로 입력 : C:\Program Files\Java\jdk1.8.0_301
[디렉터리 정보]
이름 : jdk1.8.0_301
--> [폴더] bin
--> [파일] COPYRIGHT (3244 bytes)
--> [폴더] include
--> [파일] javafx-src.zip (5235470 bytes)
--> [파일] jmc.txt (195 bytes)
--> [폴더] jre
--> [폴더] legal
--> [폴더] lib
--> [파일] LICENSE (44 bytes)
--> [파일] README.html (159 bytes)
--> [파일] release (488 bytes)
--> [파일] src.zip (21176403 bytes)
--> [파일] THIRDPARTYLICENSEREADME-JAVAFX.txt (190 bytes)
--> [파일] THIRDPARTYLICENSEREADME.txt (190 bytes)
파일 - 경로이동 예제
경로 이동
상위 경로로 이동 또는 하위 경로로 이동
package api.io.file;
import java.io.File;
public class Test05 {
public static void main(String[] args) {
File f = new File("sample", "test.txt");
f = f.getAbsoluteFile();// 절대 경로를 기준으로 파일 객체를 재생성
System.out.println(f.getAbsolutePath());
// 상위 경로로 이동(탐색기의 ↑ 화살표)
// File dir = f의 상위 파일 객체;
File dir = f.getParentFile();
System.out.println(dir.getAbsolutePath());
dir = dir.getParentFile();
System.out.println(dir.getAbsolutePath());
// 하위 경로로 이동(대상 디렉터리의 이름이 필요)
dir = new File(dir, "sample");
System.out.println(dir.getAbsolutePath());
}
}
파일 - 생성 및 삭제
파일 또는 디렉터리의 생성 및 삭제
파일과 디렉터리는 생성 명령이 다르다
이름만으로는 파일인지 디렉터리인지 구분할 수 없기 때문에 명령 자체가 다르다
package api.io.file;
import java.io.File;
public class Test06 {
public static void main(String[] args) {
// 1. 디렉터리 생성
File a = new File("sample/a/b/c/d");
// boolean result = a.mkdir();//중간 경로가 없는 경우에는 생성하지 않는 명령
boolean result = a.mkdirs();// 중간 경로까지 생성하는 명령
System.out.println("result = " + result);
// a.delete();
// 응용 - 사용자 폴더에 academy 폴더 만들기
String home = System.getProperty("user.home");
System.out.println("home = " + home);
File aca = new File(home, "academy");
aca.mkdirs();
System.out.println("폴더 생성 완료!");
// aca.delete();
}
}
result = false
home = C:\Users\user
폴더 생성 완료!
파일입출력 - 개요 및 싱글바이트 출력
Single Byte 출력
준비물 : FileOutputStream, File
package api.io.single;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Test01 {
public static void main(String[] args) throws IOException {
// 파일 생성
File target = new File("sample", "single.txt");
target.createNewFile();
// 파일 출력 스트림 생성
OutputStream out = new FileOutputStream(target);
// 구조 : [프로그램] → out → target → [single.txt]
// 파일 출력 :
out.write(104);// h
out.write(101);// e
out.write(108);// l
out.write(108);// l
out.write(111);// o
out.write(9);// tab(\t)
out.write('J');
out.write('a');
out.write('v');
out.write('a');
out.write('\n');// enter(10)
// byte를 초과한 데이터(50000 ---> 80로 강제변환)
// =byte를 초과한 데이터 넣어도 의미없다
// =단순하게 편의성을 위해 데이터 넣어도 의미없다
// =50000 ---> (byte)50000 --->0
out.write(50000);
// 통로는 반드시 마지막에 닫아야한다(cf : Scanner)
out.close();
}
}
Single Byte 입력
준비물 : FileInputStream, File 객체
방법[1] File에 들어있는 byte 수만큼 읽어오도록 구현
package api.io.single;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Test02_1 {
public static void main(String[] args) throws IOException {
File target = new File("sample", "single.txt");
FileInputStream in = new FileInputStream(target);
// 구조 : [프로그램] ← in ← target ← [single.txt]
// [1] File에 들어있는 byte 수만큼 읽어오도록 구현
for (long i = 0; i < target.length(); i++) {
int data = in.read();
System.out.println("data = " + data);
}
// 통로 정리
in.close();
}
}
방법[2] EOF(-1) 지점까지 읽도록 구현
package api.io.single;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Test02_2 {
public static void main(String[] args) throws IOException {
File target = new File("sample", "single.txt");
FileInputStream in = new FileInputStream(target);
// 구조 : [프로그램] ← in ← target ← [single.txt]
// [2] EOF(-1) 지점까지 읽도록 구현
while (true) {
int data = in.read();
if (data == -1)
break;
System.out.println("data = " + data);
}
// 통로 정리
in.close();
}
}
- 과제
다음 요구사항에 맞게 파일을 만들고 입출력을 수행하세요.
- 요구사항
- 프로젝트 내의 sample 폴더에 origin.txt 파일을 만들고 "hello java!"를 5줄 작성한 뒤 저장
- 프로젝트 내의 sample 폴더에 copy.txt 파일을 만든다
- origin.txt 파일의 내용을 copy.txt에 복사한다.
- origin.txt의 내용을 불러와서 copy.txt 파일에 그대로 내보낸다
- 더이상 내보낼 데이터가 없을 때까지 동일한 작업을 반복한다.
package api.io.single;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Test03 {
public static void main(String[] args) throws Exception {
// 1. origin.txt 생성
File origin = new File("sample", "origin.txt");
// origin.createNewFile();
FileOutputStream originOut = new FileOutputStream(origin);
for (int i = 0; i < 5; i++) {
originOut.write('h');
originOut.write('e');
originOut.write('l');
originOut.write('l');
originOut.write('o');
originOut.write('\t');
originOut.write('J');
originOut.write('a');
originOut.write('v');
originOut.write('a');
originOut.write('!');
originOut.write('\n');
}
originOut.close();
// 2. copy.txt 생성
File copy = new File("sample", "copy.txt");
// copy.createNewFile();
// 3. origin.txt → copy.txt 복사
FileOutputStream copyOut = new FileOutputStream(copy);
FileInputStream originIn = new FileInputStream(origin);
while (true) {
int data = originIn.read();
if (data == -1)
break;
copyOut.write(data);
}
copyOut.close();
originIn.close();
// copy.delete();
}
}
'Java 웹 개발' 카테고리의 다른 글
21.09.16 - 웹 개발 입문 27일차 (0) | 2021.09.16 |
---|---|
21.09.15 - 웹 개발 입문 26일차 (0) | 2021.09.15 |
21.09.13 - 웹 개발 입문 24일차 (0) | 2021.09.14 |
21.09.10 - 웹 개발 입문 23일차 (0) | 2021.09.10 |
21.09.09 - 웹 개발 입문 22일차 (0) | 2021.09.09 |