Publish:

ํƒœ๊ทธ: ,

์นดํ…Œ๊ณ ๋ฆฌ:

์ด์ „ ๊ธ€์—์„œ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ์ด์šฉํ•ด ๋ฉ”๋‰ด๊ด€๋ฆฌ๋ฅผ ๊ฐœ์„ ํ•ด๋ดค๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋ฐ์ดํ„ฐ ์ €์žฅ/์กฐํšŒ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์•„๋‹Œ ํŒŒ์ผ์— ์“ฐ๊ณ /์ฝ๋„๋ก ๋ณ€๊ฒฝํ•ด ๋ณธ๋‹ค.

ํ˜„์žฌ ๋ฉ”๋ชจ๋ฆฌ ์ƒ์—์„œ List ๊ตฌํ˜„์ฒด์— ์ €์žฅํ•˜๋Š” ๋กœ์ง๋งŒ ์žˆ๊ธฐ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์˜์†์„ฑ์„ ๊ฐ–์ง€ ์•Š๋Š”๋‹ค. ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ€ ์žˆ๋˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์ง€์›Œ์ง„๋‹ค. ์ด ๋ถ€๋ถ„์„ ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ํŒŒ์ผ์— ์ €์žฅ๋˜๋„๋ก ์ˆ˜์ •ํ•ด๋ณด์ž.

ํŒŒ์ผ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด๋“ค์ธ๋‹ค.

ํŒŒ์ผ ์ž…์ถœ๋ ฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์—, ๋จผ์ € ๊ฐ ๋ฉ”๋‰ด์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ์ž…์ถœ๋ ฅ์„ ํŽธํ•˜๊ฒŒ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด App ํด๋ž˜์Šค ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ •๋ฆฌํ•œ๋‹ค. ํ˜„์žฌ Appํด๋ž˜์Šค๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด main ๋ฉ”์†Œ๋“œ์— ์‹คํ–‰ ์ˆœ์„œ์— ๋”ฐ๋ผ ์ž‘์„ฑ๋˜์–ด ์žˆ๋‹ค.

App ํด๋ž˜์Šค ๋ฆฌํŒฉํ† ๋ง

before

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
32
33
34
35
36
37
38
39
public class App {

  public static void main(String[] args) throws Exception {
    Prompt prompt = new Prompt(System.in);

    // ํ˜„์žฌ ์†Œ์Šค์—์„œ๋Š” List ์— ์ €์žฅํ•˜๊ณ  ์žˆ๋‹ค.
    List<Board> boardRepository = new LinkedList<>();
    List<Assignment> assignmentRepository = new LinkedList<>();
    List<Member> memberRepository = new ArrayList<>();
    List<Board> greetingRepository = new ArrayList<>();
    
    // ๋ฉ”์ธ ๋ฉ”๋‰ด
    MenuGroup mainMenu = MenuGroup.getInstance("๋ฉ”์ธ");

    // ๊ณผ์ œ ๋ฉ”๋‰ด
    MenuGroup assignmentMenu = mainMenu.addGroup("๊ณผ์ œ");
    assignmentMenu.addItem("๋“ฑ๋ก", new AssignmentAddHandler(assignmentRepository, prompt));
    assignmentMenu.addItem("์กฐํšŒ", new AssignmentViewHandler(assignmentRepository, prompt));
    assignmentMenu.addItem("๋ณ€๊ฒฝ", new AssignmentModifyHandler(assignmentRepository, prompt));
    assignmentMenu.addItem("์‚ญ์ œ", new AssignmentDeleteHandler(assignmentRepository, prompt));
    assignmentMenu.addItem("๋ชฉ๋ก", new AssignmentListHandler(assignmentRepository, prompt));

    // ๊ฒŒ์‹œ๊ธ€ ๋ฉ”๋‰ด
    // ๊ฐ€์ž…์ธ์‚ฌ ๋ฉ”๋‰ด
    // ํšŒ์› ๋ฉ”๋‰ด
    // ๋„์›€๋ง ๋ฉ”๋‰ด
    
    while (true) {
      try {
        mainMenu.execute(prompt);
        prompt.close();
        break;
      } catch (Exception e) {
        System.out.println("main() ์˜ˆ์™ธ ๋ฐœ์ƒ");
      }
    }

  }
}

์—ญํ• ์— ๋”ฐ๋ผ ๋ฉ”์†Œ๋“œ๋กœ ๊ตฌ๋ถ„ํ•˜๊ณ  ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ๋กœ ๋™์ž‘ํ•˜๋„๋ก ์ˆ˜์ •ํ•ด๋ณด์ž. ๊ตฌํ˜„์„ ๋‹จ์ˆœํ™” ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋ ๋•Œ ํŒŒ์ผ์— ์ถœ๋ ฅํ•˜๊ณ , ํ”„๋กœ๊ทธ๋žจ์ด ์‹œ์ž‘๋ ๋•Œ ํŒŒ์ผ์„ ๋ชจ๋‘ ์ฝ์–ด ๋ฉ”๋ชจ๋ฆฌ์— ๋กœ๋”ฉํ•˜๊ธฐ๋กœ ํ•œ๋‹ค.

after

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public class App {

  Prompt prompt = new Prompt(System.in);
  List<Board> boardRepository = new LinkedList<>();
  List<Assignment> assignmentRepository = new LinkedList<>();
  List<Member> memberRepository = new ArrayList<>();
  List<Board> greetingRepository = new ArrayList<>();
  MenuGroup mainMenu;
  
  // ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์‹œ์ ์— ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉํ•œ๋‹ค.
  App() {
    prepareMenu();
    loadAssignment();
    loadMember();
    loadBoard();
    loadGreeting();
  }

  void prepareMenu() {
    // ๋ฉ”์ธ ๋ฉ”๋‰ด
    mainMenu = MenuGroup.getInstance("๋ฉ”์ธ");

    // ๊ณผ์ œ ๋ฉ”๋‰ด
    MenuGroup assignmentMenu = mainMenu.addGroup("๊ณผ์ œ");
    assignmentMenu.addItem("๋“ฑ๋ก", new AssignmentAddHandler(assignmentRepository, prompt));
    assignmentMenu.addItem("์กฐํšŒ", new AssignmentViewHandler(assignmentRepository, prompt));
    assignmentMenu.addItem("๋ณ€๊ฒฝ", new AssignmentModifyHandler(assignmentRepository, prompt));
    assignmentMenu.addItem("์‚ญ์ œ", new AssignmentDeleteHandler(assignmentRepository, prompt));
    assignmentMenu.addItem("๋ชฉ๋ก", new AssignmentListHandler(assignmentRepository, prompt));

    // ๊ฒŒ์‹œ๊ธ€ ๋ฉ”๋‰ด
    // ๊ฐ€์ž…์ธ์‚ฌ ๋ฉ”๋‰ด
    // ํšŒ์› ๋ฉ”๋‰ด
    // ๋„์›€๋ง ๋ฉ”๋‰ด
  }
  
  void run() {
    while (true) {
      try {
        mainMenu.execute(prompt);
        prompt.close();
        break;
      } catch (Exception e) {
        System.out.println("main() ์˜ˆ์™ธ ๋ฐœ์ƒ");
      }
    }
    // ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ ์‹œ ํŒŒ์ผ์— ๋ฐ์ดํ„ฐ ์ €์žฅ
    saveAssignment();
    saveMember();
    saveBoard();
    saveGreeting();
  }
  
  /* ์•„๋ž˜ ๋ฉ”์†Œ๋“œ๋“ค์„ ํ†ตํ•ด ํŒŒ์ผ ์ž…์ถœ๋ ฅ์„ ๋‹ค๋ฃฌ๋‹ค. */
  void saveAssignment() {
      ...
  }
  
  void loadAssignment() {
      ...
  }
  
  void saveMember() {
      ...
  }
  
  void loadMember() {
      ...
  }
  
  void saveBoard() {
      ...
  }
  
  void loadBoard() {
      ...
  }

  void saveGreeting() {
      ...
  }
  
  void loadGreeting() {
      ...
  }
  
  public static void main(String[] args) throws Exception {
    new App().run();  // App ์ƒ์„ฑ์ž ํ˜ธ์ถœ
  }
}

run()๋ฉ”์†Œ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๊ธฐ ์ „์— ๊ฐ ๋ฉ”๋‰ด์—์„œ List๊ตฌํ˜„์ฒด์— ์ €์žฅํ–ˆ๋˜ ๋ฐ์ดํ„ฐ๋“ค์„ ํŒŒ์ผ์— ์ €์žฅํ•˜๋„๋ก ํ•˜๊ณ , ํ”„๋กœ๊ทธ๋žจ ์‹œ์ž‘ ์‹œ Appํด๋ž˜์Šค ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ตœ์ดˆ ํ˜ธ์ถœํ•˜๋„๋ก ์ˆ˜์ •ํ•œ๋‹ค.

FileOutputStream

ํŒŒ์ผ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•˜๊ธฐ์œ„ํ•ด FileOutputStream๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ƒ์„ฑ์ž์— String ํƒ€์ž…์œผ๋กœ ํŒŒ์ผ๋ช…์„ ์ง€์ •ํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค. ํŒŒ์ผ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ๋Š” byte(8 bit)๋‹จ์œ„๋กœ ์ฝ์–ด ์ €์žฅํ•œ๋‹ค.

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
void saveAssignment() {
  try (FileOutputStream out = new FileOutputStream("assignment.data")) {

    // ์ถ”ํ›„ ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์‹œ ๋ฐ์ดํ„ฐ ๊ฐฏ์ˆ˜๋ฅผ for ํšŸ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ฏธ๋ฆฌ ํŒŒ์ผ์— ๊ธฐ๋กํ•ด๋‘”๋‹ค. 
    out.write(assignmentRepository.size() >> 8);
    out.write(assignmentRepository.size());

    for (Assignment assignment : assignmentRepository) {
      byte[] bytes = assignment.getTitle().getBytes(StandardCharsets.UTF_8);
      // byte๊ฐฏ์ˆ˜๋ฅผ 2๋ฐ”์ดํŠธ๋กœ ์ถœ๋ ฅ
      out.write(bytes.length >> 8);
      out.write(bytes.length);
      out.write(bytes);

      bytes = assignment.getContent().getBytes(StandardCharsets.UTF_8);
      out.write(bytes.length >> 8);
      out.write(bytes.length);
      out.write(bytes);

      out.write(assignment.getDeadline().toString().getBytes(StandardCharsets.UTF_8));
    }
  } catch (Exception e) {
    System.out.println("๊ณผ์ œ ๋ฐ์ดํ„ฐ ์ €์žฅ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ!");
    e.printStackTrace();
  }
}
  1. ์ „์ฒด ๋ฐ์ดํ„ฐ์˜ ๊ฐฏ์ˆ˜๋ฅผ ๋ฏธ๋ฆฌ ํŒŒ์ผ์— ๊ธฐ๋กํ•ด ๋‘”๋‹ค. ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์‹œ(loadAssignment()) ๋ฐ˜๋ณต ํšŸ์ˆ˜๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
    1
    2
    
      out.write(assignmentRepository.size() >> 8);
      out.write(assignmentRepository.size());
    

    FileOutputStream์˜ write()๋Š” ํ•œ๊ฐ€์ง€ ์žฌ๋ฐŒ๋Š” ์ ์ด ์žˆ๋Š”๋ฐ, ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ int ํƒ€์ž…(4byte)์„ ๋ฐ›์ง€๋งŒ ์‹ค์ œ๋กœ ์“ฐ์ด๋Š”๊ฑด ๋งจ ๋ 1 byte๋งŒ ์‚ฌ์šฉ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Š” ์˜›๋‚  C์–ธ์–ด์—์„œ ํŒŒ์ผ ์ž…์ถœ๋ ฅ์„ ๋‹ค๋ฃฐ๋•Œ์˜ API spec์„ ๊ทธ๋Œ€๋กœ ๊ณ„์Šนํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์‹ค์ œ๋กœ JVM์€ ๋‚ด๋ถ€์ ์œผ๋กœ JNI๋ฅผ ์ด์šฉํ•ด OS ์˜ API๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด๋Š” ์˜๋„์ ์œผ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ์–ธ์–ด์—์„œ ํŒŒ์ผ์ž…์ถœ๋ ฅ ๋ฐฉ์‹์„ ํ†ต์ผ์‹œํ‚ค๊ธฐ ์œ„ํ•จ์œผ๋กœ ๋ณด์ธ๋‹ค.(์Šคํƒ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์—๋„ ๋น„์Šทํ•œ ์งˆ๋ฌธ์ด ์˜ฌ๋ผ์˜จ๋‹ค.)

    img.png FileOutputStream ์˜ write()๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ OS API๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

    ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋“ค์–ด์˜ค๋Š” size()๊ฐ€ int ์ด๋ฏ€๋กœ 4byte(์–‘์ˆ˜ ๋ฐ์ดํ„ฐ๋งŒ ์•ฝ 21์–ต๊ฐœ)๋ฅผ ์ฝ์–ด์•ผ ํ•˜์ง€๋งŒ, ๊ทธ์ •๋„ ํฌ๊ธฐ์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ๋‹ค๋ฃจ๋Š” ํ”„๋กœ๊ทธ๋žจ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งจ ๋’ค 2byte ์ •๋„๋งŒ ์ฝ์–ด๋„ ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

  2. title, content ์˜ ์ •๋ณด๋ฅผ ์ฝ์–ด์™€ byte ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
    1
    2
    3
    4
    5
    
      byte[] bytes = assignment.getTitle().getBytes(StandardCharsets.UTF_8);
      // byte๊ฐฏ์ˆ˜๋ฅผ 2๋ฐ”์ดํŠธ๋กœ ์ถœ๋ ฅ
      out.write(bytes.length >> 8);
      out.write(bytes.length);   
      out.write(bytes);
    

    ์ด๋•Œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฐ ํ•ญ๋ชฉ์˜ ๊ธ€์ž์ˆ˜๋ฅผ ํ•จ๊ป˜ ํŒŒ์ผ์— ๊ธฐ๋กํ•ด ๋‘”๋‹ค. write([] byte)์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ”์ดํŠธ ๋ฐฐ์—ด ์ „์ฒด๋ฅผ ๊ธฐ๋กํ•œ๋‹ค. getDeadline()์˜ ๊ฒฝ์šฐ java.sql.Date ํƒ€์ž…์ธ๋ฐ, ์ด๋Š” toString()์„ ํ˜ธ์ถœํ•˜๋ฉด yyyy-mm-ddํ˜•์‹์œผ๋กœ ๋ฐ˜ํ™˜๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ๊ธ€์ž์ˆ˜๋ฅผ ์ง€์ •ํ•  ํ•„์š”๊ฐ€ ์—†์–ด ๋‚ ์งœ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ํŽธํ•˜๋‹ค.

FileInputStream

ํŒŒ์ผ์— ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ธฐ์œ„ํ•ด FileInputStream๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ƒ์„ฑ์ž์— String ํƒ€์ž…์œผ๋กœ ์ฝ์–ด ๋“ค์ผ ํŒŒ์ผ๋ช…์„ ์ง€์ •ํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ byte(8 bit)๋‹จ์œ„๋กœ ์ฝ์–ด์˜จ๋‹ค.

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
void loadAssignment() {
  try (FileInputStream in = new FileInputStream("assignment.data")) {
    byte[] bytes = new byte[60000];
    int size = in.read() << 8 | in.read();

    for (int i = 0; i < size; i++) {
      int len = in.read() << 8 | in.read();
      in.read(bytes, 0, len);
      String title = new String(bytes, 0, len, StandardCharsets.UTF_8);

      len = in.read() << 8 | in.read();
      in.read(bytes, 0, len);
      String content = new String(bytes, 0, len, StandardCharsets.UTF_8);

      // ๋‚ ์งœ๋Š” 10 byte ๋งŒ ์ฝ๋Š”๋‹ค
      in.read(bytes, 0, 10);
      Date deadline = Date.valueOf(new String(bytes, 0, 10, StandardCharsets.UTF_8));

      Assignment assignment = new Assignment();
      assignment.setTitle(title);
      assignment.setContent(content);
      assignment.setDeadline(deadline);

      assignmentRepository.add(assignment);
    }
  } catch (Exception e) {
    System.out.println("๊ณผ์ œ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ!");
    e.printStackTrace();
  }

}
  1. ํŒŒ์ผ์— ์ €์žฅ ์‹œ ๋งจ ์ฒ˜์Œ 2byte์— ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ ์ „์ฒด ๊ฐฏ์ˆ˜(size())๋ฅผ ์ง€์ •ํ–ˆ์œผ๋ฏ€๋กœ ์ด๋ฅผ ์ฝ์–ด์˜จ๋‹ค.
    1
    
    int size = in.read() << 8 | in.read();
    

    8bit ์™ผ์ชฝ ์ด๋™ ๋น„ํŠธ ์—ฐ์‚ฐ์˜ ๊ฒฐ๊ณผ์™€ ๋งˆ์ง€๋ง‰ ๋น„ํŠธ์˜ OR ์—ฐ์‚ฐ์„ ์ด์šฉํ•˜๋ฉด ์ด 2byte๋ฅผ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

    1
    2
    3
    
        0101
     OR 0011
      = 0111
    
  2. size๋งŒํผ ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฉด์„œ ๋ฐ์ดํ„ฐ์˜ ์ž๋ฆฟ์ˆ˜ ๋งŒํผ ๊ฐ€์ ธ์˜จ๋‹ค.
    1
    2
    
      int len = in.read() << 8 | in.read();
      in.read(bytes, 0, len);  // ์ฝ์–ด์˜จ ๋งŒํผ ๋ฒ„ํผ์— ๊ธฐ๋กํ•œ๋‹ค.
    

    ํŒŒ์ผ์— ์ž…๋ ฅ ์‹œ ๋ฐ์ดํ„ฐ ๊ฐฏ์ˆ˜์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ๋จผ์ € ์ž…๋ ฅํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ–ˆ์œผ๋ฏ€๋กœ ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ์˜ ๊ธธ์ด๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ฝ์–ด ์˜จ ๋ฐ์ดํ„ฐ์˜ ๊ธธ์ด๋ฅผ len๋ณ€์ˆ˜์— ์žฌํ• ๋‹นํ•˜๋ฉด์„œ ๊ณ„์† ์ฝ์–ด๋‚˜๊ฐ„๋‹ค. ์ด๋ฅผ ๋ฒ„ํผ(byte[] bytes = new byte[60000])์— ์ž„์‹œ ์ €์žฅํ–ˆ๋‹ค๊ฐ€ ๋ฐ”๋กœ String ๊ฐ์ฒด๋กœ ์ฝ์–ด ๋ณ€ํ™˜ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฒ„ํผ๋Š” ๊ณ„์† ์žฌ์‚ฌ์šฉ ๋œ๋‹ค. ๋‚ ์งœ์˜ ๊ฒฝ์šฐ ํ˜•์‹์ด ํ•ญ์ƒ ์ •ํ•ด์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— 10byte๋งŒ ์ฝ๋Š”๋‹ค.(yyyy-mm-dd)

    ์ฝ์–ด์˜จ ๋ฐ์ดํ„ฐ๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ๋กœ๋”ฉ ์‹œํ‚จ๋‹ค.(assignmentRepository.add(assignment))

๋ฐ์ดํ„ฐ ์ž…์ถœ๋ ฅ ํ๋ฆ„

๋ฐ์ดํ„ฐ ํ๋ฆ„

DataOutputStream / DataInputStream (wrapper class ๊ตฌํ˜„)

์ด์ „ ์ฝ”๋“œ์—์„œ FileOutputStream ๊ณผ FileInputStream ์„ ์ด์šฉํ•ด ํŒŒ์ผ ์ž…์ถœ๋ ฅ์„ ๋‹ค๋ฃจ๋ฉด์„œ ๋ถˆํŽธํ•œ ์ ์ด ์žˆ์—ˆ๋Š”๋ฐ, ๊ทธ๊ฑด ๋ฐ”๋กœ byte ํ˜•์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฌ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ํŒŒ์ผ ์ž…์ถœ๋ ฅ ์‹œ ๋ฐ”์ดํŠธ ํ•˜๋‚˜ํ•˜๋‚˜ ์ฝ์–ด์˜ค๋Š” ์ฝ”๋“œ๋ฅผ ์—ฌ๊ธฐ์ €๊ธฐ ์ค‘๋ณต์œผ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ–ˆ๋‹ค. ์ด๋Ÿฐ ๋ถ€๋ถ„์„ ๋Œ€์‹ ํ•  ํด๋ž˜์Šค(wrapper class) ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

DataOutputStream

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class DataOutputStream extends FileOutputStream {
  public DataOutputStream(String name) throws FileNotFoundException {
    super(name);
  }

  // 2 byte ์ถœ๋ ฅํ•˜๊ธฐ
  public void writeShort(int value) throws IOException {
    write(value >> 8);
    write(value);
  }

  // 4 byte ์ถœ๋ ฅํ•˜๊ธฐ
  public void writeInt(int value) throws IOException {
    write(value >> 24);
    write(value >> 16);
    write(value >> 8);
    write(value);
  }

  // 8 byte ์ถœ๋ ฅํ•˜๊ธฐ
  public void writeLong(long value) throws IOException {
    write((int) (value >> 56));
    write((int) (value >> 48));
    write((int) (value >> 40));
    write((int) (value >> 32));
    write((int) (value >> 24));
    write((int) (value >> 16));
    write((int) (value >> 8));
    write((int) value);
  }

  // ๋ฌธ์ž์—ด ์ถœ๋ ฅ
  public void writeUTF(String value) throws IOException {
    byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
    writeShort(bytes.length);
    write(bytes);
  }

  public void writeBoolean(boolean value) throws IOException {
    if (value) {
      write(1);
    } else {
      write(0);  // ์‹ค์ œ๋กœ๋Š” 0x00 ๋˜๋Š” 0x01 ์ด๋‹ค. ์ฆ‰, ๋…ผ๋ฆฌ๊ฐ’ ์ถœ๋ ฅ.
    }
  }
}

๊ธฐ์กด์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—์„œ ๋น„ํŠธ ์ด๋™ ์—ฐ์‚ฐ์„ ํ•˜๋˜ ์ฝ”๋“œ๋ฅผ ์ถ”์ถœํ•ด ๋ฉ”์†Œ๋“œ์•ˆ์—์„œ ์ž‘์—…ํ•˜๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด ์ง„๋‹ค.

saveAssignment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void saveAssignment() {
  try (DataOutputStream out = new DataOutputStream("assignment.data")) {

    // ์ €์žฅํ•  ๋ฐ์ดํ„ฐ ๊ฐฏ์ˆ˜๋ฅผ 2๋ฐ”์ดํŠธ๋กœ ์ถœ๋ ฅํ•œ๋‹ค.
    out.writeShort(assignmentRepository.size());

    for (Assignment assignment : assignmentRepository) {
      out.writeUTF(assignment.getTitle());
      out.writeUTF(assignment.getContent());
      out.writeUTF(assignment.getDeadline().toString());
    }
  } catch (Exception e) {
    System.out.println("๊ณผ์ œ ๋ฐ์ดํ„ฐ ์ €์žฅ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ!");
    e.printStackTrace();
  }
}

ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ์ดํ„ฐ๋งŒ ์ „๋‹ฌํ•ด์ฃผ๋ฉด ๋ฐ”์ดํŠธ๋ฅผ ํ•˜๋‚˜์”ฉ ์ด๋™ํ•˜๋ฉด์„œ ํŒŒ์ผ์— ์“ฐ๋Š” ์ž‘์—…์€ ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€์—์„œ ํ•œ๋‹ค.

DataInputStream

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
32
33
34
35
36
public class DataInputStream extends FileInputStream {
  public DataInputStream(String name) throws FileNotFoundException {
    super(name);
  }

  public short readShort() throws IOException {
    return (short) (read() << 8 | read());
  }

  public int readInt() throws IOException {
    return (read() << 24 | read() << 16 | read() << 8 | read());
  }

  public long readLong() throws IOException {
    return ((long) read() << 56 | 
      (long) read() << 48 | 
      (long) read() << 40 | 
      (long) read() << 32 | 
      (long) read() << 24 | 
      (long) read() << 16 | 
      (long) read() << 8 | 
      (long) read());
  }

  public boolean readBoolean() throws IOException {
    return read() == 1; // 0์ด๋ฉด false, 1์ด๋ฉด true ๋ฆฌํ„ดํ•œ๋‹ค.
  }

  public String readUTF() throws IOException {
    int len = readShort();
    //    byte[] buf = new byte[len];
    //    read(buf, 0, len);
    byte[] buf = readNBytes(len); // ์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ (java11 ๋ถ€ํ„ฐ ์ง€์›๊ฐ€๋Šฅ)
    return new String(buf, 0, len, StandardCharsets.UTF_8);
  }
}

loadAssignment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void loadAssignment() {
  try (DataInputStream in = new DataInputStream("assignment.data")) {
    int size = in.readShort();

    for (int i = 0; i < size; i++) {
      Assignment assignment = new Assignment();
      assignment.setTitle(in.readUTF());
      assignment.setContent(in.readUTF());
      assignment.setDeadline(Date.valueOf(in.readUTF()));
      assignmentRepository.add(assignment);
    }
  } catch (Exception e) {
    System.out.println("๊ณผ์ œ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ!");
    e.printStackTrace();
  }
}

์ •๋ฆฌ & ๊ฐœ์„ ์‚ฌํ•ญ

๊ธฐ์กด ์ฝ”๋“œ์—์„œ ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์ด ๋ฉ”๋ชจ๋ฆฌ ์ƒ์—์„œ๋งŒ ์ด๋ฃจ์–ด์ง€๋˜ ๊ฒƒ์„ ํŒŒ์ผ ์ž…์ถœ๋ ฅ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด ํŒŒ์ผ๋กœ ์ฝ๊ณ  ์“ฐ๋„๋ก ์ˆ˜์ •ํ–ˆ๋‹ค. ๋˜ํ•œ FileInputStream๊ณผ FileOutputStream์„ ์ƒ์†๋ฐ›์•„ ๋งŒ๋“  wrapper class๋ฅผ ์ด์šฉํ•ด ํด๋ผ์ด์–ธํŠธ์—์„œ ์ฝ”๋“œ๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์•„์ง ๋ช‡๊ฐ€์ง€ ๊ฐœ์„ ํ•ด์•ผ ํ•  ์‚ฌํ•ญ์ด ์žˆ๋‹ค. ์ฒซ๋ฒˆ์งธ๋Š” ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์ง€๋ฉด ์ž…์ถœ๋ ฅ ์†๋„๊ฐ€ ๋งค์šฐ ๋Š๋ ค์ง„๋‹ค๋Š” ์น˜๋ช…์ ์ธ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. (data seek time) ๋‘๋ฒˆ์งธ๋Š” ์ฒซ๋ฒˆ์งธ ๋ฌธ์ œ๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์†์„ ์ด์šฉํ•˜๋Š”๋ฐ, ์ด๋กœ์ธํ•ด ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•ด ์•Œ์•„๋ณธ๋‹ค. (์ƒ์†์„ ์ด์šฉํ•œ ๊ธฐ๋Šฅํ™•์žฅ ๋ฐฉ์‹์˜ ๋ฌธ์ œ์ )

๋‹ค์Œ ๊ธ€์— ์ด์–ด์„œ ๊ฐœ์„ ํ•ด ๋ณด๋„๋ก ํ•œ๋‹ค.

1. data seek time

๐Ÿ‘‰ ๋ฒ„ํผ์— ๋‹ด์•„์„œ ์ฝ๊ณ  ์“ฐ๋„๋ก ๋ณ€๊ฒฝํ•˜๊ธฐ

2. ์ƒ์†์„ ์ด์šฉํ•œ ๊ธฐ๋Šฅํ™•์žฅ ๋ฐฉ์‹์˜ ๋ฌธ์ œ์ 

๐Ÿ‘‰ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด(Decorator pattern)์„ ์ด์šฉํ•ด ๊ฐœ์„ ํ•ด๋ณด์ž.

์†Œ์Šค์ฝ”๋“œ

์†Œ์Šค์ฝ”๋“œ

๋ฐฉ๋ฌธํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋Œ“๊ธ€,์ง€์ ,ํ”ผ๋“œ๋ฐฑ ์–ธ์ œ๋‚˜ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค๐Ÿ˜Š

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ