읽기, 쓰기, 삭제 기능을 포함 한 메모장 프로그램을 만들어보자
① 우선 메모장의 읽기, 쓰기, 삭제 기능을 구현한다.
package memo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class Memo {
// init 메서드는 프로그램이 실행 될 떄마다 한번씩 호출해서 디렉토리가 있나 확인 해 주려고 생성함
public void init(String dname) { // dname을 파라미터로 받고
File dir = new File(dname);// dname 은 파일의 파라미터이기도 함
if (dir.exists() == false) { // 만약에 디렉토리를 존재하는게 아니라면
dir.mkdir(); // 디렉토리를 생성해
System.out.println(dname + "디렉토리 생성 됨"); // 그리고는 알려줘 생성 되었다고
}
}
// selctFile : 파일을 선택하는 메서드 생성
public String selectFile(String dname, Scanner sc) {
File dir = new File(dname); // 위에 String dname 을 파일 메서드로 받아
String[] fname = dir.list(); // dir.list();를 String[] fname 배열에 담아서 출력
for (int i = 0; i < fname.length; i++) {
System.out.println(i + "." + fname[i]);
// 방번호까지 프린트 하도록 했는데 왜? 그래야 선택할때 편하니까
}
// 이 중에 읽고 싶은 파일명 선택
int idx = -1; // 왜냐면 방번호는 0부터 시작하니까
System.out.println("파일번호 선택 ");
idx = sc.nextInt();
while (idx < 0 || idx >= fname.length) {
// 입력 받은 숫자가 0보다 작으면 안되고 배열의 길이보다 크면 안된다.
// 그래서 || 로 사용
}
System.out.println(fname[idx] + " 파일을 선택함"); // fname 배열의 [idx]번째 + 파일을 선택함
// dname 은 mymemo , fname[idx]; 는 선택한 방번호 -> 즉 선택한 파일이 되는 것임
// 그리고 이게 결국 최종적인 경로 (path) 가 되는거지. 왜?
return dname + fname[idx]; // (dname + fname[idx]); 이거는 (String path) 이거임
} // 이게 총 path 경로
// path 는 읽을 파일의 경로. 즉 ( dir + fname )디렉토리랑 파일 이름 합친것
public void readFile(String path) { // 파일의 내용만 골라서 읽으면 됌
// 파일 안의 a.txt/b.txt 같은 내용을 출력
// String path 변수 선언만해주고
try {
FileReader fr = new FileReader(path);// () 안에는 찾아갈 파일 경로
// 파일로 문자하나씩 받아서 출력 파라미터로 path
// path 는 결국 저기 selectFile 서 선택 된 dname + fname[idx];
// 이 애들의 경로값인거지. 파일을 선택해야 read file 을 할 수 있으니까
int ch;
while ((ch = fr.read()) != -1) {
System.out.print((char) ch);
}
fr.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 파일 받을 꺼니까 입력값 하고 같이 파라미터
public void read(String dname, Scanner sc) {
String path = selectFile(dname, sc);
readFile(path); // (선택한 파일 경로) 호출하여 파일 내용 출력
// readFile 은 위에 만든 public void readFile 이거고
}
// path 경로의 파일에 쓰기 스트림 생성 키보드 입력 받아 바로바로 출력 해주면 된다.
// boolean type flag 는 이어쓰기 모드를 할 껀지 말껀지
// true 면 이어쓰기 하겠다 아니면 안하겠다.
public void writeFile(String path, Scanner sc, boolean flag) {
// 파라미터로 받은 값으로 file writer 생성
try { // 쓰기의 기본은 지우고 다시 쓰기임
// 대신 파일 어쩌고~ 스트림을 생성할때 true를 써주면 이어쓰가가 됨.
FileWriter fw = new FileWriter(path, flag);
System.out.println("쓸 파일의 내용을 입력하고 멈추고 싶다면 /stop을 쓰세요");
// String txt = " ";
while (true) {
String txt = sc.nextLine();
if (txt.startsWith("/stop")) {
System.out.println("쓰기 종료");
break;
}
fw.write(txt);
}
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void write(String dname, Scanner sc) {
boolean flagA = false, flag = true;
// flagA는 이어쓰기, flag 는 파일명 입력 루프제한
// 원래 파일 입력을 true 로 덮어쓰기가 기본이다.
String f = " "; // 파일명
int i = 0;
File dir = new File(dname); // 메모 디렉로기 책체 생성 한것임
String[] fname = dir.list(); // 파일 목록을 일긍ㅁ
while (flag) {
// 쓰기 작업할 파일명을 입력 받아
System.out.println("파일명 : ");
f = sc.next();
for (i = 0; i < fname.length; i++) {
if (fname[i].equals(f)) { // 이름이 같은 가 다른가 봐야 함
// 따라 디렉토리 각 이름과 입력받은 파일 명이 같은지 비교 해야한다.
System.out.println("파일이 이미 존재함 \n1. 덮어쓰기 2. 이어쓰기 3.다시입력");
int m = sc.nextInt();
switch (m) {
case 1: // 덮어쓰기 할 경우에는 우리가 할게 없으니까
flag = false; // 루프를 빠져 나올 수 있게 flag 를 false로 바꿔줌
break;
case 2: // 이어쓰기 설정
flagA = true; // 이어쓰고 싶으면 계속 true
flag = false; // 안 이어쓰고 싶으면 flag false로 바꿈
break;
case 3: // 다시 입력은 스위치를 빠져 나가 그냥 while 문을 다시 돌림
break;
default:
flag = false;
break;
}
}
}
if (i == fname.length) { // 파일명 중복 안됌
break;
}
}
writeFile(dname + f, sc, flagA);
}
public void deleteFile(String path) {
try {
FileReader fr2 = new FileReader(path);
int ch;
while ((ch = fr2.read()) != -1) {
System.out.print((char) ch);
}
fr2.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void delete(String dname, Scanner sc) {
String path = selectFile(dname, sc);
File f2 = new File(path);
f2.delete();
System.out.println("선택 된 파일 삭제 되었습니다");
}
}
② Main Class에 적기 전에 메뉴 클래스를 만들어서 ① 번을 생성시켜준다
package memo;
import java.util.Scanner;
public class Menu {
private String dirPath;
private Memo memo; // 메모클래스타입
public Menu(String dirPath) {
this.dirPath = dirPath;
memo = new Memo(); // 메모클래스타입을 메뉴의 클래스로 객체화해줘
}
public void run(Scanner sc) {
memo.init(dirPath);
boolean flag = true;
int m;
while (flag) {
System.out.println("1. 읽기 2. 쓰기 3. 삭제 4. 종료");
m = sc.nextInt();
switch (m) {
case 1:
memo.read(dirPath, sc); // 같은 클래스내에서 dname 을 dirpath 라고 정의 해 줬기 때문에
break;
case 2:
memo.write(dirPath, sc);
break;
case 3:
memo.delete(dirPath, sc);
break;
case 4:
flag = false;
break;
}
}
}
}
③ main class 에 구현 시켜 준다
package memo;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
// Menu 생성자는 public Menu (String dirPath) 이라 그런 menu를 객체화 시켜 줄때
// 안의 파라미터 값을 넣어주어야 하는데 그게 string 타입이라 "mymemo/" 를 해 주었다.
// 그러면 (String dirPath)의 dirPath는 "mymemo/" 가 되는 것이다
// 그 dirPath는 Menu 안에 객체화 시켜 준 memo.init(dirPath);로 인해
// 또한, memo 클래스의 memo public void init(String dname) init 은
// (String dname) 을 사용 하니까 dirPath = dname = "mymemo/" 가 된다.
Menu m = new Menu("mymemo/");
m.run(sc);
}
}
'JAVA' 카테고리의 다른 글
[JAVA] 자바 HTTPURLConnection의 응답을 JSON 데이터로 파싱 하기 (0) | 2023.07.30 |
---|---|
자바 URLConnection과 HttpURLConnection (0) | 2023.07.29 |
[JAVA] 입출력 스트림 ⑤ 파일 복사 (0) | 2023.03.13 |
[JAVA] 입출력 스트림 ⑥ 파일 제어 및 디렉토리 (0) | 2023.03.13 |
[JAVA] 입출력 스트림 ④ 보조스트림 _ RandomAccess (0) | 2023.03.13 |