반응형
들어가기 전에
JAVA기능은
- NIO 파일 입출력 이용
- Calendar class를 이용한 날짜 표기
BBS with NIO
JAVA파일 입출력방식 중 NIO를 사용하여 게시판 작성.
class 구성
- 사용자의 명령을 입력 받는 main_bbs
- bbs의 기능(C,R,U,D) 구현 (
CRUD인데 함수명은 remove를 사용) 하는 bbs_controller - 파일 읽기 쓰기 기능을 하는 file_util
시스템 구성
- 글번호, 글쓴이, 제목, 내용, 시간이 1개의 글정보로 구성.
- 각 항목을 구분하는 DATA_SPLIT, 내용의 줄변경을 표시하는 NEW_LINE, 게시글정보의 끝을 알려주는 END_LINE은 상수로 사용
- 메뉴는 create, remove, update, read, list, exit으로 구성
- 여기서 list는 전체글의 글번호, 글쓴이, 제목을 보여줌.
- 파일은 게시판 글수를 가지는 파일과 전체 내용을 저장하는 파일로 구성.
1차 완성본으로 예외처리나 중복구문, 좋지 않은 소스코드등은 포함되어 있음.
코드 설명
- main_bbs의 main부분.
BbsController control = new BbsController(); Scanner scanner = new Scanner(System.in); String command = ""; //명령어를 입력받을 변수 선언 boolean flag = true; //시스템(?)의 끝을 알기 위한 변수 선언 while(flag) { //게시판 동작이 계속되면 무한루프. print_menu(); //메뉴 프린트 System.out.println("명령어를 입력하세요"); command = scanner.nextLine(); if ( command.equals("create")) { create(scanner, control); } else if ( command.equals("remove")) { remove(scanner, control); } else if ( command.equals("update")) { update(scanner, control); } else if ( command.equals("read")) { read(scanner, control); } else if ( command.equals("list")) { list(control); } else if ( command.equals("exit")) { flag = false; System.out.println("Turn Off. see you!"); } else //잘못입력하면 출력 { System.out.println(""); System.out.println("잘못입력... 재입력..."); System.out.println(""); } }
- main_bbs의 Create (생성)
public static void create(Scanner scanner, BbsController control) { String Input = ""; String scanline = ""; System.out.println("제목을 입력하세요."); scanline = scanner.nextLine(); Input = scanline + DATA_SPLIT; System.out.println("작성자를 입력하세요."); scanline = scanner.nextLine(); Input += scanline + DATA_SPLIT; System.out.println("내용을 입력하세요.(입력 완료 : wq)"); //내용입력... wq를 입력해야만 루틴멈춤. boolean in = true; while (in) { scanline = scanner.nextLine(); if ( Arrays.equals(scanline.toCharArray(), "wq".toCharArray())) { in = false; Input += DATA_SPLIT; }else { Input = Input+ scanline + NEW_LINE; } } String str = FileUtil.readNioBbs(DIR, IDX_NAME); //미리저장된 게시글이 있는지 파악 int count = 0; if ( isDigit(str) == true && str.length() != 0) { count = Integer.parseInt(str); count++; //미리 저장된것이 있다면 갯수에 1 추가. } else { count = 1; } Input = count + DATA_SPLIT + Input; //글번호 앞에 추가. Input = Input + control.getDate() + END_LINE; //입력일자 추가후 게시글 정보 마지막을 더함. control.createBbs(Input); //파일 저장. System.out.println(".....저장완료......"); }
- main_bbs의 Read(읽기)
public static void read(Scanner scanner, BbsController control) { System.out.println("글번호를 입력하세요."); String tStr = ""; int idx = 2; while(idx > 0) { //숫자를 입력하지 않았을 경우 1번 기회를 더줌. tStr = scanner.nextLine(); if ( isDigit(tStr) == true) { idx = -1; } else { System.out.println("숫자를 입력해주세요."); idx--; } } if ( idx == -1) { //제대로 입력되었으면. String str = control.readBbs(tStr); //파일에서 같은 글번호가 있는지 확인 if ( str == null) { System.out.println("입력한 글번호는 없습니다"); } else { print(str); //같은 게시글번호가 있으면 프린트. //이부분은 공유된 소스에 있으니 설명 생략. } } else { System.out.println("사용방법을 확인해주세요."); } }
- main_bbs의 Update(수정)
public static void update(Scanner scanner, BbsController control) { System.out.println("글번호를 입력하세요."); String tStr = ""; int idx = 2; int num = 0; while(idx > 0) { //숫자 입력을 확인하고 잘못입력시 기회 더줌. tStr = scanner.nextLine(); if ( isDigit(tStr) == true) { num = Integer.parseInt(tStr); idx = -1; } else { System.out.println("숫자를 입력해주세요."); idx--; } } if ( idx == -1) { //제대로 입력되면.. String str = control.readBbs(tStr); if ( str == null) { System.out.println("입력한 글번호는 없습니다"); } else { print(str); //수정하고자하는 글 내용 보여줌. System.out.println("수정하시겠습니까?? (yes? no?)"); tStr = scanner.nextLine(); } } else { System.out.println("사용방법을 확인해주세요."); } if (tStr.equals("yes") == true) { //수정을 원하면.. String Input = ""; String scanline = ""; //이곳은 create 부분과 거의 같음. System.out.println("제목을 입력하세요."); scanline = scanner.nextLine(); Input = scanline + DATA_SPLIT; System.out.println("작성자를 입력하세요."); scanline = scanner.nextLine(); Input += scanline + DATA_SPLIT; boolean in = true; System.out.println("내용을 입력하세요.(입력 완료 : wq"); while (in) { scanline = scanner.nextLine(); if ( Arrays.equals(scanline.toCharArray(), "wq".toCharArray())) { in = false; Input += DATA_SPLIT; }else { Input = Input+ scanline + NEW_LINE; } } Input = num + DATA_SPLIT + Input; Input = Input + control.getDate(); //여기서는 게시글 끝 구분자를 넣지 않음. control.updateBbs(num + "", Input); System.out.println(".....수정완료......"); } }
- main_bbs의 Remove (삭제)
public static void remove(Scanner scanner, BbsController control) { System.out.println("글번호를 입력하세요."); String tStr = ""; int idx = 2; int num = 0; while(idx > 0) { //글번호 이므로 숫자 입력을 체크 tStr = scanner.nextLine(); if ( isDigit(tStr) == true) { num = Integer.parseInt(tStr); idx = -1; } else { System.out.println("숫자를 입력해주세요."); idx--; } } if ( idx == -1) { //숫자면.. String str = control.readBbs(tStr); if ( str == null) { System.out.println("입력한 글번호는 없습니다"); } else { print(str); //내용 보여줌. System.out.println("정말 삭제 하시겠습니까?? (yes? no?)"); tStr = scanner.nextLine(); } } else { System.out.println("사용방법을 확인해주세요."); } if (tStr.equals("yes") == true) { //삭제를 원하면. control.removeBbs(num); //삭제. System.out.println(".....수정완료......"); } }
- main_bbs의 List(전체 글 리스트)
public static void list(BbsController control) { String[] printAll = control.listBbs().split(END_LINE); //파일에서 전체 글 받음. for (String item : printAll) { prints(item); //글번호, 글쓴이, 글제목만 프린트. } }
- BbsController의 create
public void createBbs(String str) { String cont = str; //파일 저장 FileUtil.writeNioBbs(DIR, NAME, cont); //게시판 갯수저장 count++; FileUtil.writeNioOverwrite(DIR, IDX_NAME, count + ""); }
- BbsController의 read
public String readBbs(String search) { String str = ""; // 파일 내용 읽음 str = FileUtil.readNioBbs(DIR, NAME); //각 게시글 단위로 분리 String[] sArr = str.split(END_LINE); for ( int i = 0; i < sArr.length; i++) { String[] sArr2 = sArr[i].split(DATA_SPLIT); String temp = sArr2[0].replace(DATA_SPLIT, ""); //같은 번호 있는지 체크 if ( Arrays.equals(temp.toCharArray(), search.toCharArray()) ) { //있으면 게시글내용 리턴 return sArr[i]; } } //같은 번호 없으면 null 리턴 return null; }
- BbsController의 update
public void updateBbs(String search, String content) { String str = ""; //파일에서 읽어옴. str = FileUtil.readNioBbs(DIR, NAME); String[] sArr = str.split(END_LINE); str = ""; for ( int i = 0; i < sArr.length; i++) { String[] sArr2 = sArr[i].split(DATA_SPLIT); String temp = sArr2[0].replace(DATA_SPLIT, ""); //같은 게시글 번호 확인 if ( Arrays.equals(temp.toCharArray(), search.toCharArray()) ) { //있으면 수정한 정보로 대체 sArr[i] = content; } //위에서 split으로 구분했으므로 추가. str += sArr[i] + END_LINE; } //내용 덮어씀 FileUtil.writeNioOverwrite(DIR, NAME, str); }
- BbsController의 remove
public void removeBbs(int number) { String str = ""; //파일 읽어옴. str = FileUtil.readNioBbs(DIR, NAME); String[] sArr = str.split(END_LINE); str = ""; for ( int i = 0; i < sArr.length; i++) { String[] sArr2 = sArr[i].split(DATA_SPLIT); String temp = sArr2[0].replace(DATA_SPLIT, ""); //같은 글번호가 있는지 확인. if ( temp.equals(number+"") == false ) { //같은 글번호내용을 제외하고 나머지 문자열 읽음. str += sArr[i] + END_LINE; } } //삭제된 게시글 외의 글정보 저장 FileUtil.writeNioOverwrite(DIR, NAME, str); //전체 글 갯수에서 1을 감소한후 저장. count--; FileUtil.writeNioOverwrite(DIR, IDX_NAME, count + ""); }
- BbsController의 list
public String listBbs() { //전체글 리턴 return FileUtil.readNioBbs(DIR, NAME); }
- FileUtil의 read
public static String readNioBbs(String dir, String filename) { //경로 저장 Path path = Paths.get(dir, filename); String content = ""; //파일이 있는지 확인 //boolean pathExists = Files.exists(path,new LinkOption[]{ LinkOption.NOFOLLOW_LINKS}); //http://tutorials.jenkov.com/java-nio/files.html if ( Files.exists(path,new LinkOption[]{ LinkOption.NOFOLLOW_LINKS}) == true) { try { byte rawData[] = Files.readAllBytes(path); //Format을 맞춰서 byte배열을 String 객체로 생성 content = new String(rawData, StandardCharsets.UTF_8); } catch (IOException e) { e.printStackTrace(); } finally { return content; } } else { //파일이 없으면. return null; } }
- FileUtil의 write
public static void writeNioBbs(String dir, String filename, String content) { //경로저장 Path path = Paths.get(dir, filename); try { //파일에 쓰기. Files.write(path, content.getBytes(StandardCharsets.UTF_8) //파일 포맷 , StandardOpenOption.CREATE, StandardOpenOption.APPEND ); //없으면 생성, 있으면 내용 붙이기. } catch (IOException e) { e.printStackTrace(); } }
- FileUtil의 overwrite
public static void writeNioOverwrite(String dir, String filename, String content) { //경로 Path path = Paths.get(dir, filename); try { //파일에 저장. Files.write(path, content.getBytes(StandardCharsets.UTF_8) //파일 포맷 , StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); //파일이 없으면 생성, 파일이 있으면 무시하고 생성. } catch (IOException e) { e.printStackTrace(); } }
- FileUtil의 getDate
public static String getDate() { String datetime = ""; //날짜, 시간 정보를 생성하여 받아옴. Calendar cal = Calendar.getInstance(); int[] iArr= new int[5]; int yy = cal.get(Calendar.YEAR); int mm = cal.get(Calendar.MONTH) + 1; //월 정보는 0~11이기 때문에 1을 더함. int dd = cal.get(Calendar.DATE); int ho = cal.get(Calendar.HOUR_OF_DAY); //24시간으로 표시된 시간 int mi = cal.get(Calendar.MINUTE); int se = cal.get(Calendar.SECOND); iArr[0] = mm; iArr[1] = dd; iArr[2] = ho; iArr[3] = mi; iArr[4] = se; datetime = yy +"-"; int idx = 0; for ( idx = 0; idx < 5; idx++) { if ( iArr[idx] < 10) { //월, 일, 시, 분, 초가 2자리가 아니면 앞에 0을 더해줌. datetime = datetime + 0; } switch(idx) { case 0 : //month datetime = datetime + iArr[idx] + "-"; break; case 1 : //date datetime = datetime + iArr[idx] + " "; break; case 2 : //hour datetime = datetime + iArr[idx] + ":"; break; case 3 : //minute datetime = datetime + iArr[idx] + ":"; break; case 4 : //second datetime = datetime + iArr[idx]; break; } } return datetime; }
전체파일 다운로드 - https://github.com/Teddy-Hong/BBS_withNIO.git
개선해야할 점.
- 현재 무조건 파일의 모든 정보를 가져오고 그걸 수정하여 쓰는데 이건 데이터가 커지면 문제 발생. line별로 가지고 올 수 있도록 해야함.
- 기능 분리가 아직 제대로 안됨. 각 class에 맞는 함수 정리 필요.
- 최초 작성일 : 2017.02.05. 19시 경.
반응형
'자바 > 실습(Practice)' 카테고리의 다른 글
[Java] 개발환경 만들기 - 설치(자바 Java, 이클립스 eclipse,) (0) | 2018.09.16 |
---|
댓글