JAVA

[JAVA] 입출력을 사용하여 입력 값을 받는 메모장 프로그램 만들기

해니01_15 2023. 3. 13. 18:33

읽기, 쓰기, 삭제 기능을 포함 한 메모장 프로그램을 만들어보자 

 

① 우선 메모장의 읽기, 쓰기, 삭제 기능을 구현한다.

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);

	}

}