Exercise_저장되는 단어장 만들기(메소드, 클래스, 파일저장)
Point
- Control에 Voca를 집어넣고 Main에서 불러오도록 한다.
- package를 Main, Control, Model로 각각 만든다.
모델에는 Voca 클래스를 집어넣고 private으로 설정/ Getter와 Setter를 Generate해준다.
- 중복되는 기능은 메소드로 처리해 코드 길이를 줄인다. ex_ 단어 삭제, 수정 등
각각의 메소드로 만들면 후에 오류 위치를 찾는 것도 쉽다
이때, ArrayList, String input, Scanner 같은 것들은 전체 클래스 선언으로 해준다.
- io 작업(input/output)은 네트워크 작업과 함께 가장 시간이 많이 드는 작업.
따라서 파일 io도 맨처음 시작에 위치 시켜주어야(전체클래스 선언) 호출할 때, 즉 최초 시작에만 불러오게 된다.
단어 저장은 덮어쓰기로 한다.
파일로딩을 while 문 전에 위치시킨다는 말이다.
실행창인 Main
package main;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import control.Control;
public class Main {
public static void main(String[] args) {
new Control().init();
}
}
Voca 클래스
package model;
public class Voca {
private String eng;
private String kor;
public Voca(String eng, String kor) {
this.eng = eng;
this.kor = kor;
}
public String getEng() {
return eng;
}
public void setEng(String eng) {
this.eng = eng;
}
public String getKor() {
return kor;
}
public void setKor(String kor) {
this.kor = kor;
}
}
getter(값을 가져오는)와 setter(값을 넣어주는) 위치시킴
model 패키지는 말그대로 형식을 지정하는 역할
Control 클래스
package control;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import model.Voca;
public class Control {
String input = "";
Scanner scan = new Scanner(System.in);
ArrayList<Voca> vocaArr = new ArrayList<>();
private void saveData() {
FileWriter fw;
try {
fw = new FileWriter("c:/my/voca.txt"); // 덮어쓰기 , true 붙여쓰기
for (int i = 0; i < vocaArr.size(); i++) {
String eng = vocaArr.get(i).getEng();
String kor = vocaArr.get(i).getKor();
String data = eng + "," + kor+"\r\n";
fw.write(data);
}
fw.close();
System.out.println("저장 완료");
} catch (IOException e) {
e.printStackTrace();
}
}
private void readData() {
try {
BufferedReader br = new BufferedReader(new FileReader("c:/my/voca.txt"));
while (true) {
String line = br.readLine();
if (line == null) // 읽어올 데이터가 없다
break;
String[] temp = line.split(",");
vocaArr.add(new Voca(temp[0], temp[1]));
}
br.close();
System.out.println("총 "+vocaArr.size() +"개 단어 로드");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void showVoca() {
System.out.println("[ 현 단어장 " + vocaArr.size() + "개 ]");
for (int i = 0; i < vocaArr.size(); i++) {
System.out.println((i + 1) + ". " + vocaArr.get(i).getEng() + " : " + vocaArr.get(i).getKor());
}
}
private void addVoca() {
System.out.println();
System.out.println("추가할 단어 입력하셈");
input = scan.nextLine();
System.out.println("한글 뜻?");
String kor = scan.nextLine();
vocaArr.add(new Voca(input, kor));
}
private void deleteVoca() {
System.out.println();
System.out.println("삭제할 단어를 선택해 주세요");
input = scan.nextLine();
int temp = Integer.parseInt(input);
vocaArr.remove(temp - 1);
}
private void updateVoca() {
System.out.println();
System.out.println("수정할 단어를 선택해 주세요");
input = scan.nextLine();
int temp = Integer.parseInt(input);
System.out.println("수정할 단어 입력하셈");
input = scan.nextLine();
vocaArr.get(temp - 1).setEng(input);
// engArr.set(temp - 1, input);
System.out.println("수정할 한글뜻 입력하셈");
input = scan.nextLine();
vocaArr.get(temp - 1).setKor(input);
// korArr.set(temp - 1, input);
}
private void scrambleGame() {
Random rd = new Random();
int ranNum = rd.nextInt(vocaArr.size());
String answer = vocaArr.get(ranNum).getEng();
String question = "";
ArrayList<String> tempArr = new ArrayList<String>();
for (int i = 0; i < answer.length(); i++) {
tempArr.add(answer.substring(i, i + 1));
}
while (tempArr.size() > 0) {
ranNum = rd.nextInt(tempArr.size());
question = question + tempArr.get(ranNum);
tempArr.remove(ranNum);
}
String temp = answer;
// while(temp.length() > 0) {
// ranNum = rd.nextInt(temp.length());
// question = question + temp.substring(ranNum, ranNum+1);
// temp = temp.substring(0, ranNum) + temp.substring(ranNum+1);
// System.out.println("ranNum: "+ ranNum +", question: "+question +", temp: "+ temp);
// }
System.out.println("문제: " + question);
input = scan.nextLine();
if (input.equals(answer)) {
// 정답
} else {
// 오답
}
}
public void init() {
//파일로딩
File file = new File("c:/my/voca.txt");
if(file.exists()) {
readData();
}
while (true) {
System.out.println("길이: " + vocaArr.size());
System.out.println("----------------------");
System.out.println("| 뭐할래?");
System.out.println("| 1. 추가 2. 삭제 3. 수정 4. 게임 5. 끝내기");
System.out.println("----------------------");
String input = scan.nextLine();
if (input.equals("1")) {
showVoca();
addVoca();
saveData();
} else if (input.equals("2")) {
showVoca();
deleteVoca();
saveData();
} else if (input.equals("3")) {
showVoca();
updateVoca();
saveData();
} else if (input.equals("4")) {
scrambleGame();
} else if (input.equals("5")) {
break;
} else {
System.out.println("또이 또이 안 치냐??");
}
showVoca();
System.out.println();
System.out.println();
}
}
}
Control 클래스 내에서 각 기능을 메소드로 분리한다. ***
단어장 저장하기 -> private void saveData()
단어장 읽어오기 -> private void readData()
단어장 보여주기 -> private void showVoca()
단어 추가하기 -> private void addVoca()
단어 삭제하기 -> private void deleteVoca()
단어 수정하기 -> private void updateVoca()
단어 게임하기 -> private void scrambleGame()
EX_ 파일 기능
private void saveData() {
FileWriter fw;
try {
fw = new FileWriter("c:/my/voca.txt"); // 덮어쓰기 , true 붙여쓰기
for (int i = 0; i < vocaArr.size(); i++) {
String eng = vocaArr.get(i).getEng();
String kor = vocaArr.get(i).getKor();
String data = eng + "," + kor+"\r\n";
fw.write(data);
}
fw.close();
System.out.println("저장 완료");
} catch (IOException e) {
e.printStackTrace();
}
}
private void readData() {
try {
BufferedReader br = new BufferedReader(new FileReader("c:/my/voca.txt"));
while (true) {
String line = br.readLine();
if (line == null) // 읽어올 데이터가 없다
break;
String[] temp = line.split(",");
vocaArr.add(new Voca(temp[0], temp[1]));
}
br.close();
System.out.println("총 "+vocaArr.size() +"개 단어 로드");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
BufferedReader : 콘솔로부터 라인 단위로 읽기
import java.io.BufferedReader;
FileWriter : 텍스트 데이터를 파일에 저장할 때 사용하는 문자 기반 스트림
FileWriter fw = new FileWriter("C:/Temp/file.txt,true")
FileWriter fw = new FileWriter(file, true);
기존의 파일 내용 끝에 데이터를 추가할 경우는 두번째 매개값으로 true를 준다. 디폴트값이 false이므로 덮어쓰고 싶으면 true를 안쓰면 된다.
try / catch : 예외 처리
try{
//에러가 발생할 수 있는 코드
throw new Exception(); //강제 에러 출력
}catch (Exception e){
//에러시 수행
e.printStackTrace(); //오류 출력(방법은 여러가지)
throw e; //최상위 클래스가 아니라면 무조건 던져주자
}finally{
//무조건 수행
}
finally는 생략가능하다.
참고_
e.getMessage() = 에러 이벤트와 함께 들어오는 메세지를 출력한다.
e.getMessage(): 출력문구
e.toString() = 에러 이벤트의 toString()을 호출해서 간단한 에러 메시지를 확인한다.
e.toString(): java.lang.Exception: 출력문구
e.printStackTrace() = 에러 메세지의 발생 근원지를 찾아서 단계별로 에러를 출력한다.
e.printStackTrace(): java.lang.Exception: 출력문구
at ExThrowException.main(ExeThrowException.java:6)