이번에는 입력한 데이터 값이 프로그램을 종료하면 파일에 저장이 가능하도록 만들었다.
외부데이터에 저장하고 저장된 데이터를 다시 가져오는 작업이 필요하므로 직렬화와 역직렬화의 과정이 포함된다.
import java.io.Serializable;
public class PhoneInfo implements Serializable {
private String name;
private String phoneNum;
PhoneInfo (String name, String phoneNum) {
this.name = name;
this.phoneNum = phoneNum;
}
public void showPhoneInfo() {
System.out.println("이름 : " + name);
System.out.println("전화번호 : " + phoneNum);
}
public String getName() {
return name;
}
public String getPhoneNum() {
return phoneNum;
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object obj) {
if ( obj instanceof PhoneInfo ) {
PhoneInfo pi = (PhoneInfo) obj;
if ( pi.getName().equals(name) ) {
return true;
}
}
return false;
}
public boolean contains(String name) {
return false;
}
}
PhoneInfo 클래스 내부에 수정된 건 없지만, 이번에는 외부 데이터를 저장하고 입력받기 위해 직렬화와 역직렬화의 과정을 거쳐야 하므로 Sreializable 인터페이스를 상속받기 위해 impliments 했다.
public class PhoneUnivInfo extends PhoneInfo {
private String major;
private int grade;
PhoneUnivInfo (String name, String phoneNum, String major, int grade) {
super(name, phoneNum);
this.major = major;
this.grade = grade;
}
@Override
public void showPhoneInfo() {
super.showPhoneInfo();
System.out.println("전공 : "+major);
System.out.println("학년 : "+grade);
}
}
public class PhoneCompanyInfo extends PhoneInfo {
private String company;
PhoneCompanyInfo(String name, String phoneNum, String company) {
super(name, phoneNum);
this.company = company;
}
@Override
public void showPhoneInfo() {
super.showPhoneInfo();
System.out.println("회사 : "+company);
}
}
PhoneInfo 의 자손 클래스이므로 따로 수정해야할 부분은 없었다.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashSet;
import java.util.Iterator;
public class PhoneBookManager {
static HashSet<PhoneInfo> list = new HashSet<PhoneInfo>();
// 싱글톤 : 하나의 인스턴스만 만들 수 있도록하여 공유함
private PhoneBookManager() {
}
private static PhoneBookManager instance;
public static PhoneBookManager getInstance() {
if (instance == null)
instance = new PhoneBookManager();
return instance;
}
public void readData() {
System.out.println("데이터 입력을 시작합니다.");
System.out.println("1.일반, 2.대학, 3.회사");
int kinds = PhoneBook.sc.nextInt();
PhoneBook.sc.nextLine();
System.out.print("이름 : ");
String name = PhoneBook.sc.nextLine();
System.out.print("전화번호 : ");
String phoneNum = PhoneBook.sc.nextLine();
PhoneInfo pi = null;
switch (kinds) {
case 1:
pi = new PhoneInfo(name, phoneNum);
break;
case 2:
System.out.print("전공 : ");
String major = PhoneBook.sc.nextLine();
System.out.print("학년 : ");
int grade = PhoneBook.sc.nextInt();
pi = new PhoneUnivInfo(name, phoneNum, major, grade);
break;
case 3:
System.out.print("회사 : ");
String company = PhoneBook.sc.nextLine();
pi = new PhoneCompanyInfo(name, phoneNum, company);
break;
}
list.add(pi);
System.out.println("데이터 입력이 완료되었습니다..");
}
public void searchData() {
System.out.print("데이터 검색을 시작합니다.\n검색할 이름 : ");
String name = PhoneBook.sc.nextLine();
Iterator<PhoneInfo> itr = list.iterator();
while (itr.hasNext()) {
PhoneInfo pi = itr.next();
if (name.equals(pi.getName())) {
pi.showPhoneInfo();
System.out.println("데이터 검색이 완료되었습니다.");
}
}
}
public void deleteData() {
System.out.println("데이터 삭제를 시작합니다.\n삭제할 이름 : ");
String name = PhoneBook.sc.nextLine();
Iterator<PhoneInfo> itr = list.iterator();
while (itr.hasNext()) {
PhoneInfo pi = itr.next();
if (name.equals(pi.getName())) {
list.remove(pi);
System.out.println("데이터가 삭제되었습니다.");
}
}
}
public void printAllData() {
System.out.println("데이터를 전체 출력합니다.");
System.out.println("현재 저장된 데이터의 개수는 " + list.size() + "개 입니다.");
Iterator<PhoneInfo> itr = list.iterator();
while (itr.hasNext()) {
PhoneInfo pi = itr.next();
pi.showPhoneInfo();
}
System.out.println("--------------------------");
}
public void readFromFile() {
// 전제, 파일이 있는지 없는지 확인.
// 있다면, 직렬화로 저장된 객체를 읽어서 해쉬셋 요소로 등록하기.
ObjectInputStream objInput = null;
FileInputStream fileInput = null;
String path = System.getProperty("user.dir");
// user.dir : 현재 프로젝트 파일의 경로 찾기
System.out.println("path : " + path);
File file = new File(path + "\\PhoneBook.txt");
if (!file.exists()) { // 파일이 없다면 만들어라
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
// 폴더와 파일이 생성됐다면, 해당 파일을 스트림으로 변환하여 데이터의 저장 처리할 예정.
try {
fileInput = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 파일에 데이터가 있는지 확인
try {
if (fileInput.available() > 0) { // 읽을 데이터가 있다면
// available은 데이터의 남은 바이트를 int로 반환하고
// 스트림의 끝(eof)에 도달하면 0을 반환함
objInput = new ObjectInputStream(fileInput);
while (fileInput.available() > 0) {
// 더 이상의 데이터가 없을 때까지 반복하며 리스트에 추가해라
list.add((PhoneInfo) objInput.readObject());
}
objInput.close();
} else {
System.out.println("저장된 데이터가 없습니다.");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
fileInput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void storeToFile() {
String path = System.getProperty("user.dir");
File file = new File(path + "\\PhoneBook.txt");
if (list != null) { // 리스트에 내용이 있다면
Iterator<PhoneInfo> itr = list.iterator();
ObjectOutputStream objOut = null;
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
objOut = new ObjectOutputStream(fileOut);
} catch (IOException e) {
e.printStackTrace();
}
while (itr.hasNext()) {
PhoneInfo p = itr.next();
try {
objOut.writeObject(p);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
objOut.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
기존과 내용은 동일하고, 외부에 저장된 데이터를 불러오는 readFromFile 메소드와 입력된 데이터를 외부 데이터에 저장하는 StroreToFile 메소드를 추가했다.
throws 를 사용해 예외처리를 할 수도 있지만, 일단은 예외처리를 어떤 부분에서 했는지를 각각 볼 수 있도록 복잡하더라도 일일이 try/catch를 사용했다.
import java.util.Scanner;
public class PhoneBook {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
PhoneBookManager manager = PhoneBookManager.getInstance(); // 싱글톤
manager.readFromFile();
int ch;
boolean flag = true;
while (flag) {
showMenu();
ch = sc.nextInt();
sc.nextLine(); // 엔터소거용
switch (ch) {
case 1:
manager.readData();
break;
case 2:
manager.searchData();
break;
case 3:
manager.deleteData();
break;
case 4:
manager.printAllData();
break;
case 5:
System.out.println("프로그램을 종료합니다.");
manager.storeToFile();
flag = false;
sc.close();
break;
}// end_switch
} // end_while
}// end_main
static void showMenu() {
System.out.println("메뉴를 선택하세요.");
System.out.println("----------------");
System.out.println("1.데이터 입력");
System.out.println("2.데이터 검색");
System.out.println("3.데이터 삭제");
System.out.println("4.데이터 전체출력");
System.out.println("5.프로그램 종료");
System.out.println("----------------");
}
}
프로그램이 실행되면 바로 저장된 데이터를 불러오도록 readFromFile 메소드를 위에 배치하였고,
반대로 프로그램이 끝나기 직전에 데이터를 저장하도록 storeToFile 메소드를 case 5 (프로그램 종료) 에 배치하였다.
데이터를 저장하고 나서 while문을 빠져나가도록 boolean flag를 false로 만들었다.
'개발입문 > JAVA 세미프로젝트' 카테고리의 다른 글
[JAVA] 콘솔용 POS 프로그램 만들기 (0) | 2022.10.12 |
---|---|
[JAVA] HashSet을 이용하여 중복값 저장이 안 되는 전화번호부 만들기 (0) | 2022.10.12 |
[JAVA] 상속과 오버라이딩을 이용하여 카테고리가 있는 전화번호부 만들기 (0) | 2022.10.12 |
[JAVA] 배열을 이용한 전화번호부 만들기 (0) | 2022.10.12 |
댓글