Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 컬렉션 타입
- 다형성
- 인터페이스
- oracle
- 추상메서드
- 어윈 사용법
- 대덕인재개발원
- 오라클
- 예외처리
- 참조형변수
- 정수형타입
- 컬렉션프레임워크
- exception
- GRANT VIEW
- abstract
- 집합_SET
- EnhancedFor
- 자바
- 환경설정
- 제네릭
- NestedFor
- 객체 비교
- 예외미루기
- 생성자오버로드
- 한국건설관리시스템
- cursor문
- 메소드오버로딩
- 사용자예외클래스생성
- 자동차수리시스템
- Java
Archives
- Today
- Total
거니의 velog
230907_입출력 3 본문
[DataIOTest.java]
package kr.or.ddit.basic;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataIOTest {
public static void main(String[] args) {
try {
FileOutputStream fout = new FileOutputStream("d:/d_other/test.dat");
// 기본 자료형 단위로 출력할 보조 스트림 객체 생성
DataOutputStream dout = new DataOutputStream(fout);
dout.writeInt(200); // 정수형으로 출력
dout.writeFloat(123.45f); // 실수형(float)으로 출력
dout.writeBoolean(false); // 논리형으로 출력
dout.writeUTF("ABCDabcd"); // 문자열 형식으로 출력
System.out.println("출력 완료...");
dout.close(); // 스트림 닫기
} catch (IOException e) {
e.printStackTrace();
}
}
}
package kr.or.ddit.basic;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataIOTest {
public static void main(String[] args) {
try {
FileOutputStream fout = new FileOutputStream("d:/d_other/test.dat");
// 기본 자료형 단위로 출력할 보조 스트림 객체 생성
DataOutputStream dout = new DataOutputStream(fout);
dout.writeInt(200); // 정수형으로 출력
dout.writeFloat(123.45f); // 실수형(float)으로 출력
dout.writeBoolean(false); // 논리형으로 출력
dout.writeUTF("ABCDabcd"); // 문자열 형식으로 출력
System.out.println("출력 완료...");
dout.close(); // 스트림 닫기
} catch (IOException e) {
e.printStackTrace();
}
//----------------------------------------------------------
// 출력한 자료 읽어오기
try {
FileInputStream fin = new FileInputStream("d:/d_other/test.dat");
// 기본 자료형 단위로 입력할 보조 스트림 객체 생성
DataInputStream din = new DataInputStream(fin);
// DataInputStream 으로 자료를 읽어올 때는
// DataOutputStream 으로 출력했을 때의 순서와 같은 순서로 읽어와야 된다.
System.out.println("정수형 : " + din.readInt());
System.out.println("실수형 : " + din.readFloat());
System.out.println("논리형 : " + din.readBoolean());
System.out.println("문자열 : " + din.readUTF());
System.out.println("읽기 작업 완료");
din.close(); // 스트림 닫기
} catch (IOException e) {
e.printStackTrace();
}
}
}
[ObjectIOTest.java]
package kr.or.ddit.basic;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectIOTest {
public static void main(String[] args) {
// Member의 인스턴스 생성
Member mem1 = new Member("홍길동", 20, "대전");
Member mem2 = new Member("홍길서", 30, "인천");
Member mem3 = new Member("홍길남", 40, "강릉");
Member mem4 = new Member("홍길북", 50, "포항");
// 객체를 파일에 저장하기
try {
// 출력용 스트림 객체 생성
FileOutputStream fout = new FileOutputStream("d:/d_other/member.obj");
BufferedOutputStream bout = new BufferedOutputStream(fout);
ObjectOutputStream oout = new ObjectOutputStream(bout);
// 출력 작업
System.out.println("객체 저장 작업 시작...");
oout.writeObject(mem1); // java.io.NotSerializableException: kr.or.ddit.basic.Member
oout.writeObject(mem2);
oout.writeObject(mem3);
oout.writeObject(mem4);
System.out.println("객체 저장 작업 완료...");
oout.close(); // 스트림 닫기
} catch (IOException e) {
e.printStackTrace();
}
//------------------------------------------------------------
// 저장된 객체를 읽어와 화면에 출력하기
try {
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Member implements Serializable {
private String name;
private int age;
private String addr;
// 생성자
public Member(String name, int age, String addr) {
this.name = name;
this.age = age;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "Member [name=" + name + ", age=" + age + ", addr=" + addr + "]";
}
}
package kr.or.ddit.basic;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectIOTest {
public static void main(String[] args) {
// Member의 인스턴스 생성
Member mem1 = new Member("홍길동", 20, "대전");
Member mem2 = new Member("홍길서", 30, "인천");
Member mem3 = new Member("홍길남", 40, "강릉");
Member mem4 = new Member("홍길북", 50, "포항");
// 객체를 파일에 저장하기
try {
// 출력용 스트림 객체 생성
FileOutputStream fout = new FileOutputStream("d:/d_other/member.obj");
BufferedOutputStream bout = new BufferedOutputStream(fout);
ObjectOutputStream oout = new ObjectOutputStream(bout);
// 출력 작업
System.out.println("객체 저장 작업 시작...");
oout.writeObject(mem1); // java.io.NotSerializableException: kr.or.ddit.basic.Member
oout.writeObject(mem2);
oout.writeObject(mem3);
oout.writeObject(mem4);
// readObject()메서드의 EOFException을 방지하는 방법
// 객체를 저장할 때 마지막에 null을 저장한다.
oout.writeObject(null);
System.out.println("객체 저장 작업 완료...");
oout.close(); // 스트림 닫기
} catch (IOException e) {
e.printStackTrace();
}
//------------------------------------------------------------
// 저장된 객체를 읽어와 화면에 출력하기
try {
// 입력용 스트림 객체 생성
ObjectInputStream oin = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream("d:/d_other/member.obj")
)
);
Object obj; // 읽어온 객체를 저장할 변수
// readObject()메서드가 데이터를 끝까지 다 읽어오면
// EOFException이 발생한다.
// EOF : End of File의 약자
System.out.println("----------------------------------");
while( (obj = oin.readObject()) != null ) {
// 읽어온 자료는 원래의 객체형으로 형변환 후 사용한다.
Member mem = (Member)obj;
System.out.println("이름 : " + mem.getName());
System.out.println("나이 : " + mem.getAge());
System.out.println("주소 : " + mem.getAddr());
System.out.println("----------------------------------");
}
// readObject()메서드의 EOFException을 처리하는 방법
// ==> catch블럭에서 EOFException처리를 한다.
} catch (EOFException e) {
System.out.println("출력 끝...");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Member implements Serializable {
// transient ==> 직렬화가 되지 않을 멤버변수에 지정한다.
// (직렬화 되지 않는 변수는 기본값으로 초기화 된다.)
// (기본값 ==> 참조형변수 : null, 숫자유형변수 : 0)
private String name;
private transient int age; // 나이만 직렬화를 배제하여 정보를 숨긴다.
private transient String addr;
// 생성자
public Member(String name, int age, String addr) {
this.name = name;
this.age = age;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "Member [name=" + name + ", age=" + age + ", addr=" + addr + "]";
}
}
[PhoneBookTest.java]
package kr.or.ddit.basic;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
/*
* 문제) 이름, 주소, 전화번호를 멤버로 갖는 Phone 클래스를 만들고,
* Map을 이용하여 전화번호 정보를 관리하는 프로그램을 작성하시오.
*
* (Map의 구조는 Key값으로 입력한 '이름'을 사용하고, value값으로는 'Phone클래스의 인스턴스'로 한다.)
* 변수 선언 예시) HashMap<String, Phone> 변수명;
*
* 이 프로그램에는 다음과 같은 메뉴가 있는데 각 메뉴의 기능을 구현한다.
* -----------------
* 다음 메뉴를 선택하세요.
* 1. 전화번호 등록
* 2. 전화번호 수정
* 3. 전화번호 삭제
* 4. 전화번호 검색
* 5. 전화번호 전체 출력
* 0. 프로그램 종료
* -----------------
*
* - 검색, 삭제 기능은 '이름'을 입력 받아 처리한다.
*
* 추가 조건)
* 1) '6. 전화번호 저장' 메뉴를 추가하고 구현한다.
* (저장파일명은 'phoneBookData.dat'로 한다.)
*
* 2) 프로그램이 시작될 때 저장된 파일이 있으면 그 데이터를 읽어와 Map에 셋팅한다.
*
* 3) 프로그램을 종료할 때 Map의 데이터가 변경(추가, 수정, 삭제 등) 되면
* 저장 후 종료되도록 한다.
*
* 실행 예시)
* -----------------
* 다음 메뉴를 선택하세요.
* 1. 전화번호 등록
* 2. 전화번호 수정
* 3. 전화번호 삭제
* 4. 전화번호 검색
* 5. 전화번호 전체 출력
* 0. 프로그램 종료
* -----------------
* 메뉴선택 >> 1
*
* 새롭게 등록할 전화번호 정보를 입력하세요.
* 이 름 >> 홍길동
* 전화번호 >> 010-1234-5678
* 주 소 >> 대전시 중구 오류동
*
* '홍길동' 전화번호 등록 완료!!!
*
* -----------------
* 다음 메뉴를 선택하세요.
* 1. 전화번호 등록
* 2. 전화번호 수정
* 3. 전화번호 삭제
* 4. 전화번호 검색
* 5. 전화번호 전체 출력
* 0. 프로그램 종료
* -----------------
* 메뉴선택 >> 1
*
* 새롭게 등록할 전화번호 정보를 입력하세요.
* 이 름 >> 홍길동
*
* '홍길동'은 이미 등록된 사람입니다...
*
* -----------------
* 다음 메뉴를 선택하세요.
* 1. 전화번호 등록
* 2. 전화번호 수정
* 3. 전화번호 삭제
* 4. 전화번호 검색
* 5. 전화번호 전체 출력
* 0. 프로그램 종료
* -----------------
* 메뉴선택 >> 5
*
* ----------------------------------------
* 번호 이름 전화번호 주소
* ----------------------------------------
* 1 홍길동 010-1234-5678 대전시 중구 오류동
* ~~~
* ~~~
* ----------------------------------------
* 출력 끝...
*
* -----------------
* 다음 메뉴를 선택하세요.
* 1. 전화번호 등록
* 2. 전화번호 수정
* 3. 전화번호 삭제
* 4. 전화번호 검색
* 5. 전화번호 전체 출력
* 0. 프로그램 종료
* -----------------
* 메뉴선택 >> 0
*
* 프로그램을 종료합니다.
*
*/
public class PhoneBookTest {
private HashMap<String, Phone2> phoneBookMap;
private Scanner sc;
private String fileName = "d:/d_other/phoneBookData.dat";
// 데이터가 변경되었는지 여부를 나타내는 변수 선언
// 데이터가 변경되면 이 변수값이 true가 된다.
private boolean dataChange;
// 생성자
public PhoneBookTest() {
// phoneBookMap = new HashMap<String, Phone2>();
// 생성자에서 데이터를 읽어오는 작업을 해야 함
phoneBookMap = load(); // 파일 내용을 읽어와 Map 객체에 셋팅한다.
if(phoneBookMap == null) { // 파일이 없거나 입출력 오류일 때...
phoneBookMap = new HashMap<String, Phone2>();
}
sc = new Scanner(System.in);
}
public static void main(String[] args) {
new PhoneBookTest().startPhoneBook();
}
// 저장된 전화번호 정보를 읽어와서 반환하는 메서드
private HashMap<String, Phone2> load() {
// 읽어온 데이터가 저장될 변수 선언
HashMap<String, Phone2> pMap = null;
File file = new File(fileName);
if(!file.exists()) { // 저장된 파일이 없다면...
return null;
}
// 저장된 파일이 있으면 저장된 파일을 읽어오기 위한 스트림 객체 변수 선언
ObjectInputStream oin = null;
try {
// 파일 입력용 스트림 객체 선언
oin = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(file)
)
);
// 파일 내용을 읽어와 Map 객체 변수에 저장한다.
pMap = (HashMap<String, Phone2>) oin.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(oin != null) {
try {
oin.close();
} catch (Exception e2) {}
}
}
return pMap;
}
// 프로그램을 시작하는 메서드
public void startPhoneBook() {
System.out.println("************************");
System.out.println(" 전 화 번 호 관 리 프 로 그 램");
System.out.println("************************");
while(true) {
int choice = displayMenu();
switch(choice) {
case 1: // 전화번호 등록
insert(); break;
case 2: // 전화번호 수정
update(); break;
case 3: // 전화번호 삭제
delete(); break;
case 4: // 전화번호 검색
search(); break;
case 5: // 전화번호 전체 출력
displayAll(); break;
case 6: // 전화번호 저장
save(); break;
case 0: // 프로그램 종료
if(dataChange == true) { // 데이터가 변경되었으면...
System.out.println("변경된 데이터를 저장합니다.");
save();
}
System.out.println("프로그램을 종료합니다.");
return;
default:
System.out.println("작업 번호를 잘못 입력했습니다.");
System.out.println("다시 선택하세요...");
}
}
}
// 메뉴를 출력하고 작업 번호를 입력받아 반환하는 메서드
private int displayMenu() {
System.out.println();
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("6. 전화번호 저장");
System.out.println("0. 프로그램 종료");
System.out.println("-----------------");
System.out.print("메뉴선택 >> ");
return sc.nextInt();
}
// 새로운 전화번호 정보를 등록하는 메서드 (이미 등록된 사람은 등록되지 않는다.)
private void insert() {
System.out.println();
System.out.println("새로운 전화번호 정보를 입력하세요...");
System.out.print("이 름 >> ");
String name = sc.next();
// 입력받은 이름이 이미 등록된 이름인지 검사
if(phoneBookMap.containsKey(name)) {
System.out.println(name + "씨는 이미 등록된 사람입니다...");
System.out.println("등록 작업을 마칩니다.");
return;
}
System.out.print("전화번호 >> ");
String tel = sc.next();
sc.nextLine(); // 일종의 입력 버퍼 비우기
System.out.print("주 소 >> ");
// String addr = sc.next(); // '대전시 중구 오류동' 중에 대전시만 가져가고 [데이터구분자 : 사이띄기, tab키, enter키], '중구 오류동' 중에 중구를 가져다 displayMenu()의 return sc.nextInt();와 충돌을 일으켜 오류가 뜸.
String addr = sc.nextLine(); // 처음 문장부터 enter키 이전까지 모두 가져옴. enter 키를 제외한 값을 반환함.
// String tel = sc.next(); 에 010-1234-1234[엔터키] 중에 010-1234-1234만 가져가고 구분자 [엔터키]를 남김.
// 이 구분자 [엔터키]를 String addr = sc.nextLine();이 인식해서 값을 입력받지 않고 그냥 넘어가 버림.
// 따라서 실제 주소를 입력받기 전에 이 찌꺼기(구분자 [엔터키])를 비워줘야 함.
// sc.nextLine(); 입력키를 한 번더 입력해 주면 끝.
/*
* - Scanner객체는 입력 버퍼를 이용하여 입력 작업을 수행한다.
* 즉, 입력 버퍼를 확인하여 값이 있으면 현재 입력 버퍼에 있는 값을 가져가고
* 없으면 새로운 데이터를 입력받은 후 가져간다.
*
* - Scanner의 next(), nextInt(), nextDouble() ... 등 (nextLine()을 제외한 메서드)
* ==> 이 메서드들은 사이띄기, Tab키, Enter키를 구분 문자로 분리해서 분리된 자료만 읽어간다.
*
* - Scanner의 nextLine()메서드
* ==> 한 줄 단위로 입력한다. (즉, 자료를 입력하고 Enter키를 누르면 Enter키까지 읽어간다.)
*/
// 입력 받은 정보를 이용하여 Phone2 객체 생성
// Phone2 p = new Phone2(name, tel, addr);
// phoneBookMap.put(name, p);
phoneBookMap.put(name, new Phone2(name, tel, addr));
System.out.println(name + "씨의 전화번호 정보 등록 완료!!!");
dataChange = true; // 전화번호 추가로 데이터 변경 표시
}
// 전체 전화번호 정보를 출력하는 메서드
private void displayAll() {
System.out.println();
System.out.println("----------------------------------------");
System.out.println("번호 이름 전화번호 주소");
System.out.println("----------------------------------------");
Set<String> phoneBookSet = phoneBookMap.keySet();
if(phoneBookSet.size() == 0) {
System.out.println("등록된 전화번호 정보가 하나도 없습니다...");
}else {
int cnt = 0; // 번호 출력용 변수
Iterator<String> it = phoneBookSet.iterator();
while(it.hasNext()) {
cnt++;
String key = it.next(); // 키 값(등록된 사람 이름)
Phone2 p = phoneBookMap.get(key); // Value값(Phone2 객체)
System.out.println(" " + cnt + "\t" + p.getName() + "\t" + p.getTel() + "\t" + p.getAddr());
}
}
System.out.println("----------------------------------------");
System.out.println("출력 끝...");
}
// 전화번호를 수정하는 메서드
private void update() {
System.out.println();
System.out.println("수정할 전화번호 정보를 입력하세요...");
System.out.print("이 름 >> ");
String name = sc.next();
// 해당 이름이 없으면 수정 작업을 중단한다.
if(!phoneBookMap.containsKey(name)) {
System.out.println(name + "씨의 전화번호 정보는 등록되지 않았습니다.");
System.out.println("수정 작업을 마칩니다...");
return;
}
System.out.print("새로운 전화번호 >> ");
String newTel = sc.next();
sc.nextLine(); // 일종의 입력 버퍼 비우기
System.out.print("새로운 주소 >> ");
// String newAddr = sc.next();
String newAddr = sc.nextLine();
// 같은 key값에 새로운 데이터를 셋팅한 Phone2 객체를 저장하면 된다.
phoneBookMap.put(name, new Phone2(name, newTel, newAddr));
System.out.println(name + "씨의 전화번호 정보 수정 완료!!!");
dataChange = true; // 전화번호 수정으로 데이터 변경 표시
}
// 전화번호 정보를 삭제하는 메서드
private void delete() {
System.out.println();
System.out.println("삭제할 전화번호 정보를 입력하세요.");
System.out.print("이 름 >> ");
String name = sc.next();
// 해당 이름이 없으면 삭제 작업을 중단한다.
if(!phoneBookMap.containsKey(name)) {
System.out.println(name + "씨의 전화번호 정보는 등록되지 않았습니다.");
System.out.println("삭제 작업을 마칩니다...");
return;
}
phoneBookMap.remove(name); // 삭제작업
System.out.println(name + "씨의 전화번호 정보를 삭제했습니다...");
dataChange = true; // 전화번호 삭제로 데이터 변경 표시
}
// 전화번호 정보를 검색하는 메서드
private void search() {
System.out.println();
System.out.println("검색할 전화번호 정보를 입력하세요...");
System.out.print("이 름 >> ");
String name = sc.next();
// 입력한 이름을 key값으로 Phone2 객체 가져오기
Phone2 p = phoneBookMap.get(name);
if(p==null) { // 해당 key값의 데이터가 없으면...
System.out.println(name + "씨의 전화번호 정보가 없습니다...");
}else {
System.out.println();
System.out.println(name + "씨의 전화번호 정보");
System.out.println("-----------------------");
System.out.println("이 름 : " + p.getName());
System.out.println("전화번호 : " + p.getTel());
System.out.println("주 소 : " + p.getAddr());
System.out.println("-----------------------");
}
}
// 전화번호 정보를 파일로 저장하는 메서드
private void save() {
ObjectOutputStream oout = null;
try {
// 객체 저장용 출력 스트림 객체 생성
oout = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(fileName)
)
);
// Map 객체를 파일로 저장한다.
oout.writeObject(phoneBookMap);
System.out.println("전화번호 파일 저장이 완료되었습니다...");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 사용했던 스트림 객체 닫기
if(oout != null) {
try {
oout.close();
} catch (Exception e2) {}
}
}
dataChange = false; // 데이터를 저장했으므로 굳이 프로그램 종료시 자동저장을 할 필요가 없다.
}
}
// 이름, 주소, 전화번호를 멤버로 갖는 Phone 클래스를 만들기
class Phone2 implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String tel;
private String addr;
public Phone2() {}
public Phone2(String name, String tel, String addr) {
this.name = name;
this.tel = tel;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "Phone2 [name=" + name + ", tel=" + tel + ", addr=" + addr + "]";
}
public static long getSerialVersionUid() {
return serialVersionUID;
}
}
[PhoneBookTest2.java]
package kr.or.ddit.basic;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
/*
* 문제) 이름, 주소, 전화번호를 멤버로 갖는 Phone 클래스를 만들고,
* Map을 이용하여 전화번호 정보를 관리하는 프로그램을 작성하시오.
*
* (Map의 구조는 Key값으로 입력한 '이름'을 사용하고, value값으로는 'Phone클래스의 인스턴스'로 한다.)
* 변수 선언 예시) HashMap<String, Phone> 변수명;
*
* 이 프로그램에는 다음과 같은 메뉴가 있는데 각 메뉴의 기능을 구현한다.
* -----------------
* 다음 메뉴를 선택하세요.
* 1. 전화번호 등록
* 2. 전화번호 수정
* 3. 전화번호 삭제
* 4. 전화번호 검색
* 5. 전화번호 전체 출력
* 0. 프로그램 종료
* -----------------
*
* - 검색, 삭제 기능은 '이름'을 입력 받아 처리한다.
*
* 추가 조건)
* 1) '6. 전화번호 저장' 메뉴를 추가하고 구현한다.
* (저장파일명은 'phoneBookData.dat'로 한다.)
*
* 2) 프로그램이 시작될 때 저장된 파일이 있으면 그 데이터를 읽어와 Map에 셋팅한다.
*
* 3) 프로그램을 종료할 때 Map의 데이터가 변경(추가, 수정, 삭제 등) 되면
* 저장 후 종료되도록 한다.
*
* 실행 예시)
* -----------------
* 다음 메뉴를 선택하세요.
* 1. 전화번호 등록
* 2. 전화번호 수정
* 3. 전화번호 삭제
* 4. 전화번호 검색
* 5. 전화번호 전체 출력
* 0. 프로그램 종료
* -----------------
* 메뉴선택 >> 1
*
* 새롭게 등록할 전화번호 정보를 입력하세요.
* 이 름 >> 홍길동
* 전화번호 >> 010-1234-5678
* 주 소 >> 대전시 중구 오류동
*
* '홍길동' 전화번호 등록 완료!!!
*
* -----------------
* 다음 메뉴를 선택하세요.
* 1. 전화번호 등록
* 2. 전화번호 수정
* 3. 전화번호 삭제
* 4. 전화번호 검색
* 5. 전화번호 전체 출력
* 0. 프로그램 종료
* -----------------
* 메뉴선택 >> 1
*
* 새롭게 등록할 전화번호 정보를 입력하세요.
* 이 름 >> 홍길동
*
* '홍길동'은 이미 등록된 사람입니다...
*
* -----------------
* 다음 메뉴를 선택하세요.
* 1. 전화번호 등록
* 2. 전화번호 수정
* 3. 전화번호 삭제
* 4. 전화번호 검색
* 5. 전화번호 전체 출력
* 0. 프로그램 종료
* -----------------
* 메뉴선택 >> 5
*
* ----------------------------------------
* 번호 이름 전화번호 주소
* ----------------------------------------
* 1 홍길동 010-1234-5678 대전시 중구 오류동
* ~~~
* ~~~
* ----------------------------------------
* 출력 끝...
*
* -----------------
* 다음 메뉴를 선택하세요.
* 1. 전화번호 등록
* 2. 전화번호 수정
* 3. 전화번호 삭제
* 4. 전화번호 검색
* 5. 전화번호 전체 출력
* 0. 프로그램 종료
* -----------------
* 메뉴선택 >> 0
*
* 프로그램을 종료합니다.
*
*/
public class PhoneBookTest2 {
private HashMap<String, Phone3> phoneBookMap;
private Scanner sc;
// 저장 파일명
private String fileName = "d:/d_other/phoneBookData.dat";
// 데이터가 변경되었는지 여부를 나타내는 변수
// (데이터가 변경되면 true, 그렇지 않으면 false값을 갖는다.)
private boolean dataChange;
// 생성자
public PhoneBookTest2() {
// phoneBookMap = new HashMap<String, Phone3>();
sc = new Scanner(System.in);
load();
}
public static void main(String[] args) {
new PhoneBookTest2().startPhoneBook();
}
// 전화번호 정보가 저장된 파일을 읽어오는 메서드
public void load() {
// Map 객체를 새로 생성한다.
phoneBookMap = new HashMap<String, Phone3>();
File file = new File(fileName);
// 저장된 파일이 있는지 검사
if(!file.exists()) { // 저장된 파일이 없으면...
return;
}
// 저장된 파일이 있으면 파일을 읽어와서 Map에 셋팅한다.
ObjectInputStream oin = null;
try {
// 스트림 객체 생성
oin = new ObjectInputStream(new BufferedInputStream(new FileInputStream(fileName)));
// 파일 내용 읽어오기
Object obj;
// 방법1 ==> Phone3 객체를 하나씩 저장했을 때
// while( (obj = oin.readObject()) != null ) {
// Phone3 p = (Phone3) obj; // 읽어온 데이터를 형변환 한다.
// phoneBookMap.put(p.getName(), p); // 읽어온 데이터를 Map에 셋팅한다.
// }
// 방법2 ==> Map객체 자체를 저장했을 때
obj = oin.readObject();
phoneBookMap = (HashMap<String, Phone3>) obj;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 프로그램을 시작하는 메서드
public void startPhoneBook() {
System.out.println("*****************************");
System.out.println(" 전 화 번 호 관 리 프 로 그 램 (저장가능)");
System.out.println("*****************************");
while(true) {
int choice = displayMenu();
switch(choice) {
case 1: // 전화번호 등록
insert(); break;
case 2: // 전화번호 수정
update(); break;
case 3: // 전화번호 삭제
delete(); break;
case 4: // 전화번호 검색
search(); break;
case 5: // 전화번호 전체 출력
displayAll(); break;
case 6: // 전화번호 저장
save(); break;
case 0: // 프로그램 종료
if(dataChange == true) {
save();
}
System.out.println("프로그램을 종료합니다.");
return;
default:
System.out.println("작업 번호를 잘못 입력했습니다.");
System.out.println("다시 선택하세요...");
}
}
}
// 메뉴를 출력하고 작업 번호를 입력받아 반환하는 메서드
private int displayMenu() {
System.out.println();
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("6. 전화번호 저장");
System.out.println("0. 프로그램 종료");
System.out.println("-----------------");
System.out.print("메뉴선택 >> ");
return sc.nextInt();
}
// 새로운 전화번호 정보를 등록하는 메서드 (이미 등록된 사람은 등록되지 않는다.)
private void insert() {
System.out.println();
System.out.println("새로운 전화번호 정보를 입력하세요...");
System.out.print("이 름 >> ");
String name = sc.next();
// 입력받은 이름이 이미 등록된 이름인지 검사
if(phoneBookMap.containsKey(name)) {
System.out.println(name + "씨는 이미 등록된 사람입니다...");
System.out.println("등록 작업을 마칩니다.");
return;
}
System.out.print("전화번호 >> ");
String tel = sc.next();
sc.nextLine(); // 일종의 입력 버퍼 비우기
System.out.print("주 소 >> ");
// String addr = sc.next(); // '대전시 중구 오류동' 중에 대전시만 가져가고 [데이터구분자 : 사이띄기, tab키, enter키], '중구 오류동' 중에 중구를 가져다 displayMenu()의 return sc.nextInt();와 충돌을 일으켜 오류가 뜸.
String addr = sc.nextLine(); // 처음 문장부터 enter키 이전까지 모두 가져옴. enter 키를 제외한 값을 반환함.
// String tel = sc.next(); 에 010-1234-1234[엔터키] 중에 010-1234-1234만 가져가고 구분자 [엔터키]를 남김.
// 이 구분자 [엔터키]를 String addr = sc.nextLine();이 인식해서 값을 입력받지 않고 그냥 넘어가 버림.
// 따라서 실제 주소를 입력받기 전에 이 찌꺼기(구분자 [엔터키])를 비워줘야 함.
// sc.nextLine(); 입력키를 한 번더 입력해 주면 끝.
/*
* - Scanner객체는 입력 버퍼를 이용하여 입력 작업을 수행한다.
* 즉, 입력 버퍼를 확인하여 값이 있으면 현재 입력 버퍼에 있는 값을 가져가고
* 없으면 새로운 데이터를 입력받은 후 가져간다.
*
* - Scanner의 next(), nextInt(), nextDouble() ... 등 (nextLine()을 제외한 메서드)
* ==> 이 메서드들은 사이띄기, Tab키, Enter키를 구분 문자로 분리해서 분리된 자료만 읽어간다.
*
* - Scanner의 nextLine()메서드
* ==> 한 줄 단위로 입력한다. (즉, 자료를 입력하고 Enter키를 누르면 Enter키까지 읽어간다.)
*/
// 입력 받은 정보를 이용하여 Phone3 객체 생성
// Phone3 p = new Phone3(name, tel, addr);
// phoneBookMap.put(name, p);
phoneBookMap.put(name, new Phone3(name, tel, addr));
dataChange = true;
System.out.println(name + "씨의 전화번호 정보 등록 완료!!!");
}
// 전체 전화번호 정보를 출력하는 메서드
private void displayAll() {
System.out.println();
System.out.println("----------------------------------------");
System.out.println("번호 이름 전화번호 주소");
System.out.println("----------------------------------------");
Set<String> phoneBookSet = phoneBookMap.keySet();
if(phoneBookSet.size() == 0) {
System.out.println("등록된 전화번호 정보가 하나도 없습니다...");
}else {
int cnt = 0; // 번호 출력용 변수
Iterator<String> it = phoneBookSet.iterator();
while(it.hasNext()) {
cnt++;
String key = it.next(); // 키 값(등록된 사람 이름)
Phone3 p = phoneBookMap.get(key); // Value값(Phone3 객체)
System.out.println(" " + cnt + "\t" + p.getName() + "\t" + p.getTel() + "\t" + p.getAddr());
}
}
System.out.println("----------------------------------------");
System.out.println("출력 끝...");
}
// 전화번호를 수정하는 메서드
private void update() {
System.out.println();
System.out.println("수정할 전화번호 정보를 입력하세요...");
System.out.print("이 름 >> ");
String name = sc.next();
// 해당 이름이 없으면 수정 작업을 중단한다.
if(!phoneBookMap.containsKey(name)) {
System.out.println(name + "씨의 전화번호 정보는 등록되지 않았습니다.");
System.out.println("수정 작업을 마칩니다...");
return;
}
System.out.print("새로운 전화번호 >> ");
String newTel = sc.next();
sc.nextLine(); // 일종의 입력 버퍼 비우기
System.out.print("새로운 주소 >> ");
// String newAddr = sc.next();
String newAddr = sc.nextLine();
// 같은 key값에 새로운 데이터를 셋팅한 Phone3 객체를 저장하면 된다.
phoneBookMap.put(name, new Phone3(name, newTel, newAddr));
dataChange = true;
System.out.println(name + "씨의 전화번호 정보 수정 완료!!!");
}
// 전화번호 정보를 삭제하는 메서드
private void delete() {
System.out.println();
System.out.println("삭제할 전화번호 정보를 입력하세요.");
System.out.print("이 름 >> ");
String name = sc.next();
// 해당 이름이 없으면 삭제 작업을 중단한다.
if(!phoneBookMap.containsKey(name)) {
System.out.println(name + "씨의 전화번호 정보는 등록되지 않았습니다.");
System.out.println("삭제 작업을 마칩니다...");
return;
}
phoneBookMap.remove(name); // 삭제작업
dataChange = true;
System.out.println(name + "씨의 전화번호 정보를 삭제했습니다...");
}
// 전화번호 정보를 검색하는 메서드
private void search() {
System.out.println();
System.out.println("검색할 전화번호 정보를 입력하세요...");
System.out.print("이 름 >> ");
String name = sc.next();
// 입력한 이름을 key값으로 Phone3 객체 가져오기
Phone3 p = phoneBookMap.get(name);
if(p==null) { // 해당 key값의 데이터가 없으면...
System.out.println(name + "씨의 전화번호 정보가 없습니다...");
}else {
System.out.println();
System.out.println(name + "씨의 전화번호 정보");
System.out.println("-----------------------");
System.out.println("이 름 : " + p.getName());
System.out.println("전화번호 : " + p.getTel());
System.out.println("주 소 : " + p.getAddr());
System.out.println("-----------------------");
}
}
// 전화번호 정보를 저장하는 메서드
private void save() {
ObjectOutputStream oout = null;
try {
// 스트림 객체 생성
oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
// Map의 자료 저장하기
// 방법 1 ==> Map에 저장된 Phone3 객체를 하나씩 파일로 저장하기
// for(String name : phoneBookMap.keySet()) {
// Phone3 p = phoneBookMap.get(name);
// oout.writeObject(p);
// }
// // 모든 자료가 저장된 후 마지막에 null로 저장한다.
// oout.writeObject(null);
// 방법 2 ==> Map객체 자체를 파일로 저장하기
oout.writeObject(phoneBookMap);
dataChange = false;
System.out.println("전화번호 파일 저장이 완료되었습니다...");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(oout != null) try { oout.close(); } catch (IOException e) {}
}
}
}
// 이름, 주소, 전화번호를 멤버로 갖는 Phone 클래스를 만들기
class Phone3 implements Serializable {
private String name;
private String tel;
private String addr;
public Phone3() {}
public Phone3(String name, String tel, String addr) {
this.name = name;
this.tel = tel;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "Phone3 [name=" + name + ", tel=" + tel + ", addr=" + addr + "]";
}
}
'대덕인재개발원 > 대덕인재개발원_자바기반 애플리케이션' 카테고리의 다른 글
230911_입출력 5 (0) | 2023.09.11 |
---|---|
230908_입출력 4 (0) | 2023.09.08 |
230906_입출력 2 (0) | 2023.09.06 |
230905_입출력 1 (0) | 2023.09.04 |
230904_스레드 5 (0) | 2023.09.04 |