。゚(*´□`)゚。

코딩의 즐거움과 도전, 그리고 일상의 소소한 순간들이 어우러진 블로그

[네이버클라우드] 클라우드 기반의 개발자 과정 7기/웹프로그래밍

[NC7기-45일차(6월28일)] - 웹프로그래밍 26일차

quarrrter 2023. 6. 28. 17:01

외부라이브러리를 많이 경험해보는게 익숙해지기 좋아욥 ,,! 

 

search.maven.org : 라이브러리를 잔뜩 모아놓은 사이트 

의존 라이브러리 정보를 빌드 스크립트 파일에 등록

라이브러리 다운 & 이클립스 갱신 - gradle eclipse   - referenced library (user/.gradle/caches/module/file2.1)

Eclipse IDE refresh 후 프로즈게트에서 외부 라이브러리 확인 

소스 파일에 해당 라이브러리 클래스 적용 ! 


c:/Users/bitcamp/git/bitcamp-study/

bitcamp : 사용자 홈 폴더 

git: git 저장소를 두는 폴더 

bitcamp-study: git repository (모든 깃 저장소는 항상 .git이라는 폴더를 갖고있음)

.git : 백업 폴더 / 나머지 영역: working derectory

 

깃저장소 안에 또 깃저장소를 두면 ,, 안 됨 ,,, 수정하기,,,,


문자열을 byte Stream으로 출력하기 

<<>> UML 표준화 도구: 개발자 사이에 의사소통할 수 있도록 표기하는거

<<String>> "AB가각"     file.encoding VM Properties
ucs2(utf-16) 2바이트 VM Properties(argument)의
file.encoding = utf-8
변수에 설정된 문자 규칙에 따라 변환
utf-8 형식 1. 설정하는 방법
$java -Dfile.encoding=utf-8
vm 프로퍼티 명
vm 프로퍼티 값

2. 설정하지 않으면 OS의 기본 문자 집합으로 설정
Window = MS949
mac,linux,unix = utf-8
char -> 0041( 각각 2바이트)
            0042
            AC00
            AC01
getBytes()  ->
utf-16에서 utf-8 형식으로 변환
41
42
EA B0 80
EA B0 81

이클립스는 vm 실행할 때 무조건 파일인코딩을 utf-8 옵션을 추가해서 출력함 !
이클립스 옵션 보

 System.getProperty("file.encoding")
 //"file.encoding" => 이름으로 등록되어있는 property값을 리턴함 
  byte[] bytes = str.getBytes();  
  // 문자집합을 지정하지 않으면 file.encoding에 설정된 문자집합으로 인코딩하여 리턴한다.
  
// 바이트 배열 전체를 그대로 출력한다.
    FileOutputStream out = new FileOutputStream("temp/utf.txt");
    out.write(bytes);
    out.close();
    System.out.println("데이터 출력 완료!");

powershell

원하는 캐릭터셋으로 출력가능 ! (인코딩은 UTF-8이지만 출력은 ,, 설정한대로 ,,! ?) 

// => MS949로 인코딩 하기
System.out.printf("file.encoding=%s\n", System.getProperty("file.encoding"));
byte[] bytes = str.getBytes("EUC-KR"); // UCS2 ==> EUC-KR
FileOutputStream out = new FileOutputStream("temp/ms949.txt");
out.write(bytes);
out.close();
file.encoding=UTF-8
41 42 b0 a1 b0 a2
데이터 출력 완료!
. 이클립스 같은거에-D 옵션 의존하지 말고 명시적으로 표기하기

// => UTF-8로 인코딩 하기
System.out.printf("file.encoding=%s\n", System.getProperty("file.encoding"));
byte[] bytes = str.getBytes("UTF-8"); // UCS2 ==> UTF-8

Byte Stream 텍스트 읽기 

ms949.txt

41 42 B0 A1 B0 A2

int b = 0;

// MS949로 인코딩된 텍스트 읽기
// - 단순히 1바이트를 읽어서는 안된다.
// - 영어는 1바이트를 읽으면 되지만,
// 한글은 2바이트를 읽어야 한다.
while ((b = in.read()) != -1) {
if (b >= 0x80) { // 읽은 바이트가 한글에 해당한다면
// 1바이트를 더 읽어서 기존에 읽은 바이트 뒤에 붙여 2바이트로 만든다.
b = b << 8 | in.read();  (8비트 이동)
}
System.out.printf("%x\n", b);
}
출력값
41
42
b0a1
b0a2

 

텍스트 데이터 읽기 II

// JVM 환경 변수 'file.encoding' 값
System.out.printf("file.encoding=%s\n", System.getProperty("file.encoding"));


FileInputStream in = new FileInputStream("sample/utf8.txt");


// 파일의 데이터를 한 번에 읽어보자.
byte[] buf = new byte[1000];
int count = in.read(buf); // <== 41 42 ea b0 80 ea b0 81 (AB가각)


in.close();
// 읽은 바이트 수를 출력해보자.
System.out.printf("읽은 바이트 수: %d\n", count);

// 읽은 바이트를 String 객체로 만들어보자.
String str = new String(buf, 0, count);
System.out.println(str);
출력값: 
file.encoding=UTF-8

읽은 바이트 수: 8
AB가각
 
파라미터로 주어진 바이트 배열이 어떤 character set으로 인코딩 되었는지 알려주지 않으면 JM property fille.encoding에 설정된 문자집합으로 되어있다고 가정할 것이다. 

인코딩이 잘못되어서 깨지는 거임. 바이터 배열이 어떤 캐릭터셋으로 인코딩 되었는지 안 알려줘서 그럼.
제대로 알려주기 !

FileInputStream in = new FileInputStream("sample/ms949.txt"); // 41 42 b0 a1 b0 a2(AB가각)
JVM 환경 변수 'file.encoding'에 설정된 문자표에 상관없이 String 객체를 만들 때 바이트 배열의 인코딩 문자 집합을 정확하게 알려준다면, UCS2 코드 값으로 정확하게 변환됨
FileInputStream
in = new FileInputStream("sample/ms949.txt");
String str = new String(buf, 0, count, "CP949"); // MS949 = CP949
System.out.println(str);

 
FileInputStream in = new FileInputStream("sample/utf16be.txt"); // 0041 0042 ac00 ac01(AB가각)
String str = new String(buf, 0, count, "UTF-16"); // UTF-16 == UTF-16BE
FileInputStream in = new FileInputStream("sample/utf16le.txt");
String str = new String(buf, 0, count, "UTF-16LE");

27. 프로젝트  binary stream API 사용 (데이터 저장)

 

1. Data 읽기 

2. Data 쓰기 

****

그냥 출력하면 4번이 나오기 때문에 ( write가 맨 끝꺼 출력하는 거임) 한칸이 8비라 1 출력하려면 3칸(24) 이동해야됨

 

읽기

private void loadData() {
try {
FileInputStream in = new FileInputStream("member.data");
int size = in.read() << 8;
size |= in.read();


byte[] buf = new byte[1000];


for (int i = 0; i < size; i++) {
Member member = new Member();
member.setNo(in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read());

int length = in.read() << 8     // 아래 그림 
int count = in.read(buf, 0, 3);
member.setName(new String(buf, 0, count, "UTF-8"));

프로젝트 ,, 잘 읽어보기 

 

public class App {

  ArrayList<Member> memberList = new ArrayList<>();
  LinkedList<Board> boardList = new LinkedList<>();
  LinkedList<Board> readingList = new LinkedList<>();

  BreadcrumbPrompt prompt = new BreadcrumbPrompt();

  MenuGroup mainMenu = new MenuGroup("메인");

  public App() {
    prepareMenu();
  }

  public static void main(String[] args) {
    new App().execute();
  }

  static void printTitle() {
    System.out.println("나의 목록 관리 시스템");
    System.out.println("----------------------------------");
  }

  public void execute() {
    printTitle();

    loadData();
    mainMenu.execute(prompt);
    saveData();

    prompt.close();
  }

  private void loadData() {
    loadMember();
    loadBoard();
    //loadReading();
  }

  private void saveData() {
    saveMember();
    saveBoard();
    //saveReading();
  }

  private void prepareMenu() {
    MenuGroup memberMenu = new MenuGroup("회원");
    memberMenu.add(new Menu("등록", new MemberAddListener(memberList)));
    memberMenu.add(new Menu("목록", new MemberListListener(memberList)));
    memberMenu.add(new Menu("조회", new MemberDetailListener(memberList)));
    memberMenu.add(new Menu("변경", new MemberUpdateListener(memberList)));
    memberMenu.add(new Menu("삭제", new MemberDeleteListener(memberList)));
    mainMenu.add(memberMenu);

    MenuGroup boardMenu = new MenuGroup("게시글");
    boardMenu.add(new Menu("등록", new BoardAddListener(boardList)));
    boardMenu.add(new Menu("목록", new BoardListListener(boardList)));
    boardMenu.add(new Menu("조회", new BoardDetailListener(boardList)));
    boardMenu.add(new Menu("변경", new BoardUpdateListener(boardList)));
    boardMenu.add(new Menu("삭제", new BoardDeleteListener(boardList)));
    mainMenu.add(boardMenu);

    MenuGroup readingMenu = new MenuGroup("독서록");
    readingMenu.add(new Menu("등록", new BoardAddListener(readingList)));
    readingMenu.add(new Menu("목록", new BoardListListener(readingList)));
    readingMenu.add(new Menu("조회", new BoardDetailListener(readingList)));
    readingMenu.add(new Menu("변경", new BoardUpdateListener(readingList)));
    readingMenu.add(new Menu("삭제", new BoardDeleteListener(readingList)));
    mainMenu.add(readingMenu);

    Menu helloMenu = new Menu("안녕!");
    helloMenu.addActionListener(new HeaderListener());
    helloMenu.addActionListener(new HelloListener());
    helloMenu.addActionListener(new FooterListener());
    mainMenu.add(helloMenu);
  }

  private void loadMember() {
    try {
      FileInputStream in = new FileInputStream("member.data");
      int size = in.read() << 8;
      size |= in.read();

      byte[] buf = new byte[1000];

      for (int i = 0; i < size; i++) {
        Member member = new Member();
        member.setNo(in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read());

        int length = in.read() << 8 | in.read();
        in.read(buf, 0, length);
        member.setName(new String(buf, 0, length, "UTF-8"));

        length = in.read() << 8 | in.read();
        in.read(buf, 0, length);
        member.setEmail(new String(buf, 0, length, "UTF-8"));

        length = in.read() << 8 | in.read();
        in.read(buf, 0, length);
        member.setPassword(new String(buf, 0, length, "UTF-8"));

        member.setGender((char)(in.read() << 8 | in.read()));

        memberList.add(member);
      }

      in.close();

    } catch (Exception e) {
      System.out.println("회원 정보를 읽는 중 오류 발생!");
    }
  }

  private void loadBoard() {
    try {
      FileInputStream in = new FileInputStream("board.data");
      int size = in.read() << 8;
      size |= in.read();

      byte[] buf = new byte[1000];

      for (int i = 0; i < size; i++) {
        Board board = new Board();
        board.setNo(in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read());

        int length = in.read() << 8 | in.read();
        in.read(buf, 0, length);
        board.setTitle(new String(buf, 0, length, "UTF-8"));

        length = in.read() << 8 | in.read();
        in.read(buf, 0, length);
        board.setContent(new String(buf, 0, length, "UTF-8"));

        length = in.read() << 8 | in.read();
        in.read(buf, 0, length);
        board.setWriter(new String(buf, 0, length, "UTF-8"));

        length = in.read() << 8 | in.read();
        in.read(buf, 0, length);
        board.setPassword(new String(buf, 0, length, "UTF-8"));

        board.setViewCount(in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read());

        board.setCreatedDate(
            (long)in.read() << 56
            | (long)in.read() << 48
            | (long)in.read() << 40
            | (long)in.read() << 32
            | (long)in.read() << 24
            | (long)in.read() << 16
            | (long)in.read() << 8
            | in.read());

        boardList.add(board);
      }

      in.close();

    } catch (Exception e) {
      System.out.println("회원 정보를 읽는 중 오류 발생!");
    }
  }

  private void saveMember() {
    try {
      FileOutputStream out = new FileOutputStream("member.data");

      // 저장할 데이터의 개수를 먼저 출력한다.
      int size = memberList.size();
      out.write(size >> 8);
      out.write(size);

      for (Member member : memberList) {
        int no = member.getNo();
        out.write(no >> 24);
        out.write(no >> 16);
        out.write(no >> 8);
        out.write(no);

        byte[] bytes = member.getName().getBytes("UTF-8");
        // 출력할 바이트의 개수를 2바이트로 표시한다.
        out.write(bytes.length >> 8);
        out.write(bytes.length);

        // 문자열의 바이트를 출력한다.
        out.write(bytes);


        bytes = member.getEmail().getBytes("UTF-8");
        out.write(bytes.length >> 8);
        out.write(bytes.length);
        out.write(bytes);

        bytes = member.getPassword().getBytes("UTF-8");
        out.write(bytes.length >> 8);
        out.write(bytes.length);
        out.write(bytes);

        char gender = member.getGender();
        out.write(gender >> 8);
        out.write(gender);
      }
      out.close();

    } catch (Exception e) {
      System.out.println("회원 정보를 저장하는 중 오류 발생!");
    }
  }

  private void saveBoard() {
    try {
      FileOutputStream out = new FileOutputStream("board.data");

      // 저장할 데이터의 개수를 먼저 출력한다.
      int size = boardList.size();
      out.write(size >> 8);
      out.write(size);

      for (Board board : boardList) {
        int no = board.getNo();
        out.write(no >> 24);
        out.write(no >> 16);
        out.write(no >> 8);
        out.write(no);

        byte[] bytes = board.getTitle().getBytes("UTF-8");
        out.write(bytes.length >> 8);
        out.write(bytes.length);
        out.write(bytes);


        bytes = board.getContent().getBytes("UTF-8");
        out.write(bytes.length >> 8);
        out.write(bytes.length);
        out.write(bytes);

        bytes = board.getWriter().getBytes("UTF-8");
        out.write(bytes.length >> 8);
        out.write(bytes.length);
        out.write(bytes);

        bytes = board.getPassword().getBytes("UTF-8");
        out.write(bytes.length >> 8);
        out.write(bytes.length);
        out.write(bytes);

        int viewCount = board.getViewCount();
        out.write(viewCount >> 24);
        out.write(viewCount >> 16);
        out.write(viewCount >> 8);
        out.write(viewCount);

        long createdDate = board.getCreatedDate();
        out.write((int)(createdDate >> 56));
        out.write((int)(createdDate >> 48));
        out.write((int)(createdDate >> 40));
        out.write((int)(createdDate >> 32));
        out.write((int)(createdDate >> 24));
        out.write((int)(createdDate >> 16));
        out.write((int)(createdDate >> 8));
        out.write((int)createdDate);
      }
      out.close();

    } catch (Exception e) {
      System.out.println("게시글 정보를 저장하는 중 오류 발생!");
    }
  }

}

 

 

 

 

 

 

.data   member.data txt 파일에 정보 저장됨 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

28 상속을 이용하여 바이트 입출력 기능을 확장하기 

FileInputStream/FileOutputStream + primitive type & String  입출력 기능