Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
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
Tags
more
Archives
Today
Total
관리 메뉴

개발자입니다

[Java] 예제 소스 정리 - 파일 입출력 본문

네이버클라우드 AIaaS 개발자 양성과정 1기/Java

[Java] 예제 소스 정리 - 파일 입출력

끈기JK 2023. 1. 30. 19:46

com/eomcs/io/ex01~15

 

 

예제 소스 정리

 

파일 입출력

 

 

com/eomcs/io/ex01

 

 

폴더 정보 조회 - java.io.File 클래스
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0110 {

  public static void main(String[] args) throws Exception {
    // File 클래스
    // => 디렉토리나 파일을 다룰 때 사용하는 클래스이다.
    // => 디렉토리나 파일을 생성, 삭제, 변경할 수 있다.

    // 현재 디렉토리를 조회
    // => '.' 으로 표현한다.
    // => JVM을 실행하는 위치가 현재 폴더이다.
    // => 이클립스 : 프로젝트 디렉토리를 가리킨다.
    // => 콘솔 : 현재 명령어를 실행하는 위치를 가리킨다.
    //
    File currentDir = new File("./src/main/java");
    System.out.printf("폴더명: %s\n", currentDir.getName());
    System.out.printf("경로: %s\n", currentDir.getPath());
    System.out.printf("절대경로: %s\n", currentDir.getAbsolutePath());
    System.out.printf("계산된 절대경로: %s\n", currentDir.getCanonicalPath());

    System.out.printf("총크기: %d\n", currentDir.getTotalSpace());
    System.out.printf("남은크기: %d\n", currentDir.getFreeSpace());
    System.out.printf("가용크기: %d\n", currentDir.getUsableSpace());

    System.out.printf("디렉토리여부: %b\n", currentDir.isDirectory());
    System.out.printf("파일여부: %b\n", currentDir.isFile());
    System.out.printf("감춤폴더: %b\n", currentDir.isHidden());
    System.out.printf("존재여부: %b\n", currentDir.exists());
    System.out.printf("실행가능여부: %b\n", currentDir.canExecute());
  }

}

 

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0120 {

  public static void main(String[] args) throws Exception {
    // File 클래스
    // => 파일이나 디렉토리 정보를 관리
    // => 파일이나 디렉토리를 생성,삭제,변경

    // 상위 폴더 정보 조회
    // - ".." 으로 경로를 표시한다.
    //
    File currentDir = new File("./src/main/java/../../test/java");
    System.out.printf("폴더명: %s\n", currentDir.getName());
    System.out.printf("경로: %s\n", currentDir.getPath());
    System.out.printf("절대경로: %s\n", currentDir.getAbsolutePath());
    System.out.printf("계산된 절대경로: %s\n", currentDir.getCanonicalPath());

    System.out.printf("총크기: %d\n", currentDir.getTotalSpace());
    System.out.printf("남은크기: %d\n", currentDir.getFreeSpace());
    System.out.printf("가용크기: %d\n", currentDir.getUsableSpace());

    System.out.printf("디렉토리여부: %b\n", currentDir.isDirectory());
    System.out.printf("파일여부: %b\n", currentDir.isFile());
    System.out.printf("감춤폴더: %b\n", currentDir.isHidden());
    System.out.printf("존재여부: %b\n", currentDir.exists());
    System.out.printf("실행가능여부: %b\n", currentDir.canExecute());
  }

}

 

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0130 {

  public static void main(String[] args) throws Exception {
    // File 클래스
    // => 파일이나 디렉토리 정보를 관리
    // => 파일이나 디렉토리를 생성,삭제,변경

    // 존재하지 않는 폴더 조회
    //
    File currentDir = new File("./haha");
    System.out.printf("폴더명: %s\n", currentDir.getName());
    System.out.printf("경로: %s\n", currentDir.getPath());
    System.out.printf("절대경로: %s\n", currentDir.getAbsolutePath());
    System.out.printf("계산된 절대경로: %s\n", currentDir.getCanonicalPath());

    // 존재하지 않는 폴더인 경우 크기는 0이다.
    System.out.printf("총크기: %d\n", currentDir.getTotalSpace());
    System.out.printf("남은크기: %d\n", currentDir.getFreeSpace());
    System.out.printf("가용크기: %d\n", currentDir.getUsableSpace());

    // 존재하지 않는 폴더인 경우 정보를 알아낼 수 없다. 모두 false
    System.out.printf("디렉토리여부: %b\n", currentDir.isDirectory());
    System.out.printf("파일여부: %b\n", currentDir.isFile());
    System.out.printf("감춤폴더: %b\n", currentDir.isHidden());
    System.out.printf("존재여부: %b\n", currentDir.exists());
    System.out.printf("실행가능여부: %b\n", currentDir.canExecute());
  }

}

 

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0210 {

  public static void main(String[] args) throws Exception {
    // File 클래스
    // => 파일이나 디렉토리 정보를 관리
    // => 파일이나 디렉토리를 생성,삭제,변경

    // 현재 파일 정보 조회
    //
    File file1 = new File("./src/main/java/Hello2.java");
    System.out.printf("파일명: %s\n", file1.getName());
    System.out.printf("파일크기: %d\n", file1.length());
    System.out.printf("경로: %s\n", file1.getPath());
    System.out.printf("절대경로: %s\n", file1.getAbsolutePath());
    System.out.printf("계산된 절대경로: %s\n", file1.getCanonicalPath());

    // 존재하지 않는 폴더인 경우 크기를 알아낼 수 없다.
    System.out.printf("총크기: %d\n", file1.getTotalSpace());
    System.out.printf("남은크기: %d\n", file1.getFreeSpace());
    System.out.printf("가용크기: %d\n", file1.getUsableSpace());

    // 존재하지 않는 폴더인 경우 정보를 알아낼 수 없다. 모두 false
    System.out.printf("디렉토리여부: %b\n", file1.isDirectory());
    System.out.printf("파일여부: %b\n", file1.isFile());
    System.out.printf("감춤여부: %b\n", file1.isHidden());
    System.out.printf("존재여부: %b\n", file1.exists());
    System.out.printf("실행가능여부: %b\n", file1.canExecute());
  }

}

 

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0220 {

  public static void main(String[] args) throws Exception {
    // File 클래스
    // => 파일이나 디렉토리 정보를 관리
    // => 파일이나 디렉토리를 생성,삭제,변경

    // 존재하지 않는 파일 정보 조회
    //
    File file1 = new File("./src/main/java/Hello100.java");
    System.out.printf("파일명: %s\n", file1.getName());
    System.out.printf("파일크기: %d\n", file1.length());
    System.out.printf("경로: %s\n", file1.getPath());
    System.out.printf("절대경로: %s\n", file1.getAbsolutePath());
    System.out.printf("계산된 절대경로: %s\n", file1.getCanonicalPath());

    // 존재하지 않는 폴더인 경우 크기를 알아낼 수 없다.
    System.out.printf("총크기: %d\n", file1.getTotalSpace());
    System.out.printf("남은크기: %d\n", file1.getFreeSpace());
    System.out.printf("가용크기: %d\n", file1.getUsableSpace());

    // 존재하지 않는 폴더인 경우 정보를 알아낼 수 없다. 모두 false
    System.out.printf("디렉토리여부: %b\n", file1.isDirectory());
    System.out.printf("파일여부: %b\n", file1.isFile());
    System.out.printf("감춤여부: %b\n", file1.isHidden());
    System.out.printf("존재여부: %b\n", file1.exists());
    System.out.printf("실행가능여부: %b\n", file1.canExecute());
  }

}

 

 

디렉토리 생성
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0310 {

  public static void main(String[] args) throws Exception {
    // 1) 생성할 디렉토리 경로 설정
    // - 폴더 경로를 지정하지 않으면 현재 폴더를 의미한다.
    //
    File dir = new File("temp");
    if (dir.mkdir()) { // 디렉토리 생성
      System.out.println("temp 디렉토리를 생성하였습니다.");
    } else {
      System.out.println("temp 디렉토리를 생성할 수 없습니다.");
    }
  }
}

 

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0320 {

  public static void main(String[] args) throws Exception {

    File dir = new File("temp/a");

    // 하위 디렉토리 생성하기
    //
    if (dir.mkdir()) {
      System.out.println("temp/a 디렉토리를 생성하였습니다.");
    } else {
      System.out.println("temp/a 디렉토리를 생성할 수 없습니다.");
    }
  }
}

 

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0321 {

  public static void main(String[] args) throws Exception {

    File dir = new File("temp2/a");

    // 존재하지 않는 폴더 아래에 새 폴더를 만들 때
    // => 존재하지 않는 폴더가 자동 생성되지 않는다.
    // => 따라서 그 하위 폴더를 생성할 수 없다.
    //
    if (dir.mkdir()) {
      System.out.println("temp2/a 디렉토리를 생성하였습니다.");
    } else {
      System.out.println("temp2/a 디렉토리를 생성할 수 없습니다.");
    }
  }
}

 

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0322 {

  public static void main(String[] args) throws Exception {

    File dir = new File("temp2/a/b");

    // 디렉토리를 생성할 때 존재하지 않는 중간 디렉토리도 만들고 싶다면,
    // mkdirs()를 호출하라.
    //
    // mkdirs()
    // - 지정된 경로에 디렉토리가 존재하지 않으면 그 디렉토리도 만든다.
    //
    if (dir.mkdirs()) {
      System.out.println("temp2/a/b 디렉토리를 생성하였습니다.");
    } else {
      System.out.println("temp2/a/b 디렉토리를 생성할 수 없습니다.");
    }
  }
}

 

 

디렉토리 삭제
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0330 {

  public static void main(String[] args) throws Exception {

    File dir = new File("temp");

    if (dir.delete()) {
      System.out.println("temp 디렉토리를 삭제하였습니다.");
    } else {
      // 디렉토리 안에 파일이나 다른 하위 디렉토리가 있다면 삭제할 수 없다.
      // 또한 존재하지 않는 디렉토리도 삭제할 수 없다.
      System.out.println("temp 디렉토리를 삭제할 수 없습니다.");
    }
  }
}

 

 

파일 생성
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0410 {

  public static void main(String[] args) throws Exception {
    // 생성할 파일의 경로 설정
    File file = new File("temp2/a/test.txt");

    if (file.createNewFile()) { // 파일 생성
      System.out.println("test.txt 파일을 생성하였습니다.");
    } else {
      // 이미 파일이 있다면 다시 생성할 수 없다.
      // 해당 경로에 디렉토리가 없다면 파일을 생성할 수 없다. 예외 발생!
      System.out.println("test.txt 파일을 생성할 수 없습니다.");
    }
  }
}

 

 

파일 삭제
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0420 {

  public static void main(String[] args) throws Exception {
    // 삭제할 파일의 경로 설정
    File file = new File("temp2/a/test.txt");

    if (file.delete()) { // 파일 삭제
      System.out.println("test.txt 파일을 삭제하였습니다.");
    } else {
      // 존재하지 않는 파일은 삭제할 수 없다.
      // 경로가 존재하지 않으면 당연히 그 경로에 파일이 없으니까 삭제할 수 없다.
      System.out.println("test.txt 파일을 삭제할 수 없습니다.");
    }
  }
}

 

 

특정 폴더를 생성하여 그 폴더에 파일을 만든다.
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0430 {

  public static void main(String[] args) throws Exception {
    // 생성할 파일의 경로 설정
    File file = new File("temp/b/test.txt");
    // 디렉토리가 존재하지 않으면 파일을 생성할 수 없다.
    // - 예외 발생!

    if (file.createNewFile()) { // 파일 생성
      System.out.println("test.txt 파일을 생성하였습니다.");
    } else {
      System.out.println("test.txt 파일을 생성할 수 없습니다.");
    }
  }
}

 

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0431 {

  public static void main(String[] args) throws Exception {
    // 생성할 파일의 경로 설정
    File file = new File("temp/b/test.txt");

    // 파일을 생성하기 전에 존재하지 않는 폴더를 생성하고 싶다면,
    //    String path = file.getParent(); // => temp/b
    //    File dir = new File(path);
    File dir = file.getParentFile(); // 위의 코드와 같다.
    System.out.println(dir.getCanonicalPath());

    // 먼저 디렉토리를 생성한다.
    if (dir.mkdirs()) {
      System.out.println("디렉토리를 생성하였습니다.");
    } else {
      System.out.println("디렉토리를 생성할 수 없습니다.");
    }

    // 그런 후 파일을 생성한다.
    if (file.createNewFile()) { // 파일 생성
      System.out.println("파일을 생성하였습니다.");
    } else {
      System.out.println("파일을 생성할 수 없습니다.");
    }
  }
}

 

 

디렉토리에 들어 있는 파일이나 하위 디렉토리 정보 알아내기
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0510 {

  public static void main(String[] args) throws Exception {

    // 현재 폴더의 정보를 알아낸다.
    File dir = new File(".");

    // 현재 폴더에 있는 파일이나 하위 디렉토리 이름을 알아내기
    String[] names = dir.list();

    for (String name : names) {
      System.out.println(name);
    }
  }
}

 

 

디렉토리에 들어 있는 파일이나 하위 디렉토리 정보 알아내기 II
package com.eomcs.io.ex01;

import java.io.File;
import java.sql.Date;

public class Exam0520 {

  public static void main(String[] args) throws Exception {

    File dir = new File(".");

    // 파일이나 디렉토리 정보를 File 객체로 받기
    // => File은 디렉토리와 파일을 통칭하는 용어다.
    //
    File[] files = dir.listFiles();

    for (File file : files) {
      System.out.printf("%s   %s %12d %s\n",
          file.isDirectory() ? "d" : "-",
              new Date(file.lastModified()),
              file.length(),
              file.getName());
    }
  }
}

 

 

디렉토리에 들어있는 파일(디렉토리) 목록을 꺼낼 때 필터 적용하기
package com.eomcs.io.ex01;

import java.io.File;
import java.io.FilenameFilter;

public class Exam0610 {

  public static void main(String[] args) throws Exception {

    class JavaFilter implements FilenameFilter {
      @Override
      public boolean accept(File dir/* 부모 경로 */, String name /* 파일,디렉토리 이름 */) {
        // 이 메서드는 list()에서 호출한다.
        // 해당 폴더에 들어 있는 파일이나 디렉토리를 찾을 때 마다 호출한다.
        // (하위 폴더 아래는 뒤지지 않는다)
        // 이 메서드에서 해야 할 일은 찾은 파일이나 디렉토리를
        // 리턴할 배열에 포함시킬지 여부이다.
        // true를 리턴하면 배열에 포함되고,
        // false를 리턴하면 배열에 포함되지 않는다.

        // 파일,디렉토리 이름이 .java 로 끝나는 경우만 리턴 배열에 포함시키다.
        if (name.endsWith(".java"))
          return true; // 조회 결과에 포함시켜라!
        return false; // 조회 결과에서 제외하라!
      }
    }

    File dir = new File(".");

    // => 확장자가 .java 인 파일의 이름만 추출하기
    // 1) 필터 준비
    JavaFilter javaFilter = new JavaFilter();

    // 2) 필터를 사용하여 디렉토리의 목록을 가져오기
    String[] names = dir.list(javaFilter);

    for (String name : names) {
      System.out.println(name);
    }

    // 문제점:
    // - temp.java 는 디렉토리이다.
    // - 현재의 필터는 파일 이름으로만 검사한다.
    // - 파일인지 디렉토리인지 여부는 검사하지 않는다.
    // - 해결책?
    //   다음 예제를 보라!
  }
}

 

 

package com.eomcs.io.ex01;

import java.io.File;
import java.io.FilenameFilter;

public class Exam0611 {

  public static void main(String[] args) throws Exception {

    class JavaFilter implements FilenameFilter {
      @Override
      public boolean accept(File dir, String name) {

        // 해당 이름이 디렉토리 이름인지 파일 이름인지 알아내려면
        // File 객체를 생성해야 한다.
        //
        File file = new File(dir, name);
        // 디렉토리 정보와 이름을 합쳐 파일 객체를 생성할 수 있다.

        if (file.isFile() && name.endsWith(".java"))
          return true; // 조회 결과에 포함시켜라!
        return false; // 조회 결과에서 제외하라!
      }
    }

    File dir = new File(".");

    // => 확장자가 .java 인 파일의 이름만 추출하기
    // 1) 필터 준비
    JavaFilter javaFilter = new JavaFilter();

    // 2) 필터를 사용하여 디렉토리의 목록을 가져오기
    String[] names = dir.list(javaFilter);

    for (String name : names) {
      System.out.println(name);
    }
  }
}

 

 

디렉토리에 들어있는 파일(디렉토리) 목록을 꺼낼 때 필터 적용하기 II
package com.eomcs.io.ex01;

import java.io.File;
import java.io.FileFilter;

public class Exam0620 {

  public static void main(String[] args) throws Exception {

    class JavaFilter implements FileFilter {
      @Override
      public boolean accept(File file) {
        // 이 메서드는 listFiles() 메서드에서 호출한다.
        // 지정한 폴더에 들어 있는 파일이나 디렉토리를 찾을 때 마다 호출한다.
        // 리턴 값 File[] 에 찾은 파일 정보를 포함시킬지 여부를 결정한다.
        // true 이면 배열에 포함시키고,
        // false 이면 배열에서 제외한다.
        //
        if (file.isFile() && file.getName().endsWith(".java"))
          return true; // 조회 결과에 포함시켜라!
        return false; // 조회 결과에서 제외하라!
      }
    }

    File dir = new File(".");

    // => 확장자가 .java 인 파일의 이름만 추출하기
    // 1) 필터 준비
    JavaFilter javaFilter = new JavaFilter();

    // 2) 필터를 사용하여 디렉토리의 목록을 가져오기
    File[] files = dir.listFiles(javaFilter);

    for (File file : files) {
      System.out.printf("%s %12d %s\n",
          file.isDirectory() ? "d" : "-",
              file.length(),
              file.getName());
    }
  }
}

 

 

익명 클래스로 FileFilter 만들기
package com.eomcs.io.ex01;

import java.io.File;
import java.io.FileFilter;

public class Exam0630 {


  public static void main(String[] args) throws Exception {

    // 필터 객체를 한 개만 만들 것이라면
    // 익명 클래스로 정의하는 것이 낫다.
    //
    FileFilter filter = new FileFilter() {
      @Override
      public boolean accept(File file) {
        if (file.isFile() && file.getName().endsWith(".java"))
          return true;
        return false;
      }
    };

    File dir = new File(".");

    File[] files = dir.listFiles(filter);

    for (File file : files) {
      System.out.printf("%s %12d %s\n", file.isDirectory() ? "d" : "-", file.length(),
          file.getName());
    }
  }
}

 

 

package com.eomcs.io.ex01;

import java.io.File;
import java.io.FileFilter;

public class Exam0640 {


  public static void main(String[] args) throws Exception {

    File dir = new File(".");

    // 익명 클래스를 정의할 때
    // 객체를 사용할 위치에 익명 클래스를 정의하는 것이
    // 코드를 더 읽기 쉽게 만든다.
    //
    File[] files = dir.listFiles(new FileFilter() {
      @Override
      public boolean accept(File file) {
        if (file.isFile() && file.getName().endsWith(".java"))
          return true;
        return false;
      }
    });

    for (File file : files) {
      System.out.printf("%s %12d %s\n", file.isDirectory() ? "d" : "-", file.length(),
          file.getName());
    }
  }
}

 

 

람다로 FileFilter 만들기
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0650 {

  public static void main(String[] args) throws Exception {

    File dir = new File(".");

    // 메서드 한 개짜리 인터페이스인 경우
    // 람다(lambda) 문법을 사용하면 훨씬 더 간결하게 코드를 작성할 수 있다.
    //
    // lambda class
    // => 메서드가 한 개짜리인 경우 lambda 표현식을 사용할 수 있다.
    // => 문법:
    //      (파라미터, 파라미터, ...) -> 문장 한개
    //      (파라미터, 파라미터, ...) -> { 문장1; 문장2; 문장3;}
    //      () -> 문장 한개
    //      () -> {문장1; 문장2; 문장3;}
    //
    File[] files = dir.listFiles(file -> {
      if (file.isFile() && file.getName().endsWith(".java"))
        return true;
      return false;
    });

    for (File file : files) {
      System.out.printf("%s %12d %s\n", file.isDirectory() ? "d" : "-", file.length(),
          file.getName());
    }
  }
}

 

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0651 {

  public static void main(String[] args) throws Exception {

    File dir = new File(".");

    // 메서드 한 개짜리 인터페이스인 경우 
    // 람다(lambda) 문법을 사용하면 훨씬 더 간결하게 코드를 작성할 수 있다.
    // => (조건) ? 값1 : 값2
    File[] files = dir.listFiles(file -> 
    (file.isFile() && file.getName().endsWith(".java")) ? true : false);

    for (File file : files) {
      System.out.printf("%s %12d %s\n", file.isDirectory() ? "d" : "-", file.length(),
          file.getName());
    }
  }
}

 

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0652 {

  public static void main(String[] args) throws Exception {

    File dir = new File(".");

    // 메서드 한 개짜리 인터페이스인 경우 
    // 람다(lambda) 문법을 사용하면 훨씬 더 간결하게 코드를 작성할 수 있다.
    // => expression 은 return 문장을 생략할 수 있다.
    File[] files = dir.listFiles(file -> file.isFile() && file.getName().endsWith(".java"));

    for (File file : files) {
      System.out.printf("%s %12d %s\n", file.isDirectory() ? "d" : "-", file.length(),
          file.getName());
    }
  }
}

 

 

활용: 필터와 Lambda 표현식을 사용하여 디렉토리 이름만 추출하라.
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0660 {

  public static void main(String[] args) throws Exception {

    File file = new File(".");

    File[] files = file.listFiles(f -> f.isDirectory());

    for (File f : files) {
      System.out.printf("%s %12d %s\n",
          f.isDirectory() ? "d" : "-",
              f.length(),
              f.getName());
    }
  }
}

 

 

활용 - 지정한 폴더 및 그 하위 폴더까지 모두 검색하여 파일 및 디렉토리 이름을 출력하라.
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0710_01 {

  public static void main(String[] args) throws Exception {

    // 결과 예)
    // /Users/bitcamp/git/test
    // src/
    //   main/
    //     java/
    //       com/
    //         Hello.java
    //         Hello2.java
    // build.gradle
    // settings.gradle
    // Hello.java
    // ...

    File dir = new File(".");
    System.out.println(dir.getCanonicalPath());
  }
}

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0710_02 {

  public static void main(String[] args) throws Exception {

    // 결과 예)
    // /Users/bitcamp/git/test
    // src/
    //   main/
    //     java/
    //       com/
    //         Hello.java
    //         Hello2.java
    // build.gradle
    // settings.gradle
    // Hello.java
    // ...
    
    File dir = new File(".");
    System.out.println(dir.getCanonicalPath());
    
    printList(dir);
  }

  static void printList(File dir) {
    
  }
}

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0710_03 {

  public static void main(String[] args) throws Exception {

    // 결과 예)
    // /Users/bitcamp/git/test
    // src/
    //   main/
    //     java/
    //       com/
    //         Hello.java
    //         Hello2.java
    // build.gradle
    // settings.gradle
    // Hello.java
    // ...
    
    File dir = new File(".");
    System.out.println(dir.getCanonicalPath());
    
    printList(dir);
  }

  static void printList(File dir) {
    // 현재 디렉토리의 하위 파일 및 디렉토리 목록을 알아낸다.
    File[] files = dir.listFiles();

    // 리턴 받은 파일 배열에서 이름을 꺼내 출력한다.
    for (File file : files) {
      System.out.println(file.getName());
    }
  }
}

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0710_04 {

  public static void main(String[] args) throws Exception {

    // 결과 예)
    // /Users/bitcamp/git/test
    // src/
    //   main/
    //     java/
    //       com/
    //         Hello.java
    //         Hello2.java
    // build.gradle
    // settings.gradle
    // Hello.java
    // ...

    File dir = new File(".");
    System.out.println(dir.getCanonicalPath());

    printList(dir);
  }

  static void printList(File dir) {
    // 현재 디렉토리의 하위 파일 및 디렉토리 목록을 알아낸다.
    File[] files = dir.listFiles();

    // 리턴 받은 파일 배열에서 이름을 꺼내 출력한다.
    for (File file : files) {
      if (file.isDirectory() && !file.isHidden()) {
        System.out.printf("%s/\n", file.getName());
      } else if (file.isFile()) {
        System.out.printf("%s\n", file.getName());
      }
    }
  }
}

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0710_05 {

  public static void main(String[] args) throws Exception {

    // 결과 예)
    // /Users/bitcamp/git/test
    // src/
    //   main/
    //     java/
    //       com/
    //         Hello.java
    //         Hello2.java
    // build.gradle
    // settings.gradle
    // Hello.java
    // ...

    File dir = new File(".");
    System.out.println(dir.getCanonicalPath());

    printList(dir);
  }

  static void printList(File dir) {
    // 현재 디렉토리의 하위 파일 및 디렉토리 목록을 알아낸다.
    File[] files = dir.listFiles();

    // 리턴 받은 파일 배열에서 이름을 꺼내 출력한다.
    for (File file : files) {
      if (file.isDirectory() && !file.isHidden()) {
        System.out.printf("%s/\n", file.getName());
        printList(file);  // 하위 디렉토리 출력 재귀함수 호출
      } else if (file.isFile()) {
        System.out.printf("%s\n", file.getName());
      }
    }
  }
}

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0710_06 {

  public static void main(String[] args) throws Exception {

    // 결과 예)
    // /Users/bitcamp/git/test
    // src/
    //   main/
    //     java/
    //       com/
    //         Hello.java
    //         Hello2.java
    // build.gradle
    // settings.gradle
    // Hello.java
    // ...

    File dir = new File(".");
    System.out.println(dir.getCanonicalPath());

    printList(dir, 1);
  }

  static void printList(File dir, int level) {
    // 현재 디렉토리의 하위 파일 및 디렉토리 목록을 알아낸다.
    File[] files = dir.listFiles();

    // 리턴 받은 파일 배열에서 이름을 꺼내 출력한다.
    for (File file : files) {
      for (int i = 0; i < level; i++) {
        System.out.print("  ");
      }

      if (file.isDirectory() && !file.isHidden()) {
        System.out.printf("%s/\n", file.getName());
        printList(file, level + 1);
      } else if (file.isFile()) {
        System.out.printf("%s\n", file.getName());
      }
    }
  }
}

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0710_07 {

  public static void main(String[] args) throws Exception {

    // 결과 예)
    // /Users/bitcamp/git/test
    // src/
    //   main/
    //     java/
    //       com/
    //         Hello.java
    //         Hello2.java
    // build.gradle
    // settings.gradle
    // Hello.java
    // ...

    File dir = new File(".");
    System.out.println(dir.getCanonicalPath());

    printList(dir, 1);
  }

  static void printList(File dir, int level) {
    // 현재 디렉토리의 하위 파일 및 디렉토리 목록을 알아낸다.
    File[] files = dir.listFiles();

    // 리턴 받은 파일 배열에서 이름을 꺼내 출력한다.
    for (File file : files) {
      printIndent(level);

      if (file.isDirectory() && !file.isHidden()) {
        System.out.printf("%s/\n", file.getName());
        printList(file, level + 1);
      } else if (file.isFile()) {
        System.out.printf("%s\n", file.getName());
      }
    }
  }

  static void printIndent(int level) {
    for (int i = 0; i < level; i++) {
      System.out.print("  ");
    }
  }
}

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0710_08 {

  public static void main(String[] args) throws Exception {

    // 결과 예)
    // /Users/bitcamp/git/test
    // src/
    //   main/
    //     java/
    //       com/
    //         Hello.java
    //         Hello2.java
    // build.gradle
    // settings.gradle
    // Hello.java
    // ...

    File dir = new File(".");
    System.out.println(dir.getCanonicalPath());

    printList(dir, 1);
  }

  static void printList(File dir, int level) {
    // 현재 디렉토리의 하위 파일 및 디렉토리 목록을 알아낸다.
    File[] files = dir.listFiles();

    // 리턴 받은 파일 배열에서 이름을 꺼내 출력한다.
    for (File file : files) {
      printIndent(level);

      if (file.isDirectory() && !file.isHidden()) {
        System.out.printf("%s/\n", file.getName());
        printList(file, level + 1);
      } else if (file.isFile()) {
        System.out.print("\\--");
        System.out.printf("%s\n", file.getName());
      }
    }
  }

  static void printIndent(int level) {
    for (int i = 0; i < level; i++) {
      System.out.print("  ");
    }
  }
}

 

 

활용 - 지정한 폴더를 삭제하라.
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0720_01 {

  public static void main(String[] args) throws Exception {

    // temp 디렉토리를 삭제하기
    File dir = new File("temp");
  }
}

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0720_02 {

  public static void main(String[] args) throws Exception {

    // temp 디렉토리를 삭제하기
    File dir = new File("temp");

    deleteFile(dir);
  }

  static void deleteFile(File dir) {

  }
}

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0720_03 {

  public static void main(String[] args) throws Exception {

    // temp 디렉토리를 삭제하기
    File dir = new File("temp");

    deleteFile(dir);
  }

  static void deleteFile(File dir) {
    dir.delete(); // 현재 파일이나 폴더를 지우기
  }
}

 

package com.eomcs.io.ex01;

import java.io.File;

public class Exam0720_04 {

  public static void main(String[] args) throws Exception {

    // temp 디렉토리를 삭제하기
    File dir = new File("temp");

    deleteFile(dir);
  }

  static void deleteFile(File dir) {
    // 주어진 파일이 디렉토리라면 하위 파일이나 디렉토리를 찾아 지운다.
    if (dir.isDirectory()) {
      File[] files = dir.listFiles();
      for (File file : files) {
        deleteFile(file);
      }
    }

    dir.delete(); // 현재 파일이나 폴더 지우기
  }
}

 

 

활용 - 지정한 폴더에서 .class 파일만 찾아 출력하라.
package com.eomcs.io.ex01;

import java.io.File;
import java.io.FileFilter;

public class Exam0730 {

  public static void main(String[] args) throws Exception {

    File dir = new File("bin/main");
    System.out.println(dir.getCanonicalPath());

    printClasses(dir);
  }

  static void printClasses(File dir) {

    File[] files = dir.listFiles(new FileFilter() {
      @Override
      public boolean accept(File pathname) {
        return pathname.isDirectory() || (pathname.isFile() && pathname.getName().endsWith(".class"));
      }
    });

    for (File file : files) {
      if (file.isDirectory()) {
        printClasses(file);
      } else {
        System.out.printf("%s\n", file.getName());
      }
    }
  }
}

 

 

활용 - 클래스 파일 이름을 출력할 때 패키지 이름을 포함하라.
package com.eomcs.io.ex01;

import java.io.File;
import java.io.FileFilter;

public class Exam0731 {

  public static void main(String[] args) throws Exception {

    // 클래스 이름을 출력할 때 패키지 이름을 포함해야 한다.
    // 예) ch01.Test01
    // 예) ch22.a.Test14
    //
    File dir = new File("bin/main");
    System.out.println(dir.getCanonicalPath());

    printClasses(dir, "");
  }

  static void printClasses(File dir, String packageName) {

    File[] files = dir.listFiles(new FileFilter() {
      @Override
      public boolean accept(File pathname) {
        return pathname.isDirectory() || (pathname.isFile() && pathname.getName().endsWith(".class"));
      }
    });

    if (packageName.length() > 0) {
      packageName += ".";
    }

    for (File file : files) {
      if (file.isDirectory()) {
        printClasses(file, packageName + file.getName());

      } else {
        // path가 파일이면 패키지 이름과 파일 이름을 합쳐 출력하고 리턴한다.
        // => 단 파일 이름에서 .class 확장자 명은 제외한다.
        // => 파일 명이 Hello.class 이고 패키지명이 aaa.bbb 라면
        //    출력할 이름은 aaa.bbb.Hello 이다.
        System.out.println(packageName + file.getName().replace(".class", ""));
      }
    }
  }
}

 

 

활용 - 클래스 파일 이름을 출력할 때 패키지 이름을 포함하라. (람다 문법 활용)
package com.eomcs.io.ex01;

import java.io.File;

public class Exam0732 {

  public static void main(String[] args) throws Exception {

    // 클래스 이름을 출력할 때 패키지 이름을 포함해야 한다.
    // 예) ch01.Test01
    // 예) ch22.a.Test14
    //
    File dir = new File("bin/main");
    System.out.println(dir.getCanonicalPath());

    printClasses(dir, "");
  }

  static void printClasses(File dir, String packageName) {

    // 기존의 익명 클래스를 람다 문법으로 교체한다.
    File[] files = dir.listFiles(
        f -> f.isDirectory() || (f.isFile() && f.getName().endsWith(".class")));

    if (packageName.length() > 0) {
      packageName += ".";
    }

    for (File file : files) {
      if (file.isDirectory()) {
        printClasses(file, packageName + file.getName());

      } else {
        System.out.println(packageName + file.getName().replace(".class", ""));
      }
    }
  }
}

 

 

 

com/eomcs/io/ex02

 

 

Byte Stream - 바이트 단위로 출력하기
package com.eomcs.io.ex02;

import java.io.FileOutputStream;

public class Exam0110 {

  public static void main(String[] args) throws Exception {

    // 1) 파일로 데이터를 출력하는 객체를 준비한다.
    // - new FileOutputStream(파일경로)
    // - 지정된 경로에 해당 파일을 자동으로 생성한다.
    // - 기존에 같은 이름의 파일이 있으면 덮어쓴다.
    // - 주의! 기존 파일이 삭제된다.
    // - 파일 경로가 절대 경로가 아니면
    //   - 리눅스,유닉스: / 로 시작하지 않으면,
    //   - 윈도우: c:\, d:\ 등으로 시작하지 않으면,
    //   현재 디렉토리가 기준이 된다.
    FileOutputStream out = new FileOutputStream("temp/test1.data");

    // 2) 1바이트를 출력한다.
    // => write(int) : 1바이트를 출력하는 메서드이다.
    //    파라미터의 타입이 int라고 해서 4바이트를 출력하는 것이 아니다.
    //    오직 맨 끝 1바이트만 출력한다.
    out.write(0x7a6b5c4d); // 출력하는 값은 0x4d 이다.
    out.write(2);     // 0x00000002
    out.write(40);    // 0x00000028
    out.write(100);   // 0x00000064
    out.write(101);   // 0x00000065
    out.write(102);   // 0x00000066
    out.write(127);   // 0x0000007f
    out.write(255);   // 0x000000ff
    out.write('A');   // 0x0041
    out.write('가');  // 0xac00

    // 3) 출력 도구를 닫는다.
    // - OS에서 관리하는 자원 중에서 한정된 개수를 갖는 자원에 대해
    //   여러 프로그램이 공유하는 경우, 항상 사용 후 OS에 반납해야 한다.
    // - 그래야 다른 프로그램이 해당 자원을 사용할 수 있다.
    //   예) 파일, 메모리, 네트워크 연결 등
    // - 이런 자원을 사용하는 클래스는 자원을 해제시키는 close()라는 메서드가 있다.
    // - 보통 java.lang.AutoCloseable 인터페이스를 구현하고 있다.
    // - 이번 예제에서 다루는 FileOutputStream 클래스에도 close()가 있다.
    // - 따라서 FileOutputStream 객체를 사용한 후에는 close()를 호출하여
    //   사용한 자원을 해제시켜야 한다.
    // - close()를 호출하면,
    //   FileOutputStream이 작업하는 동안 사용했던 버퍼(임시메모리)를 비운다.
    // - OS에서 제공한 파일과의 연결을 끊는다.
    //
    out.close();
    // 물론, JVM을 종료하면 JVM을 실행하는 동안 사용했던 모든 자원은
    // 자동으로 해제된다.
    // 이런 예제처럼 짧은 시간 동안만  실행되는 경우,
    // close()를 호출하지 않아도 자원을 해제시키는데 문제가 없다.
    // 문제는 24시간 365일 멈추지 않고 실행하는 서버 프로그램인 경우
    // 사용한 자원을 즉시 해제시키지 않으면
    // 자원 부족 문제가 발생한다.
    // 결론!
    // - 간단한 코드를 작성하더라도 AutoCloseable 인터페이스를 구현한 클래스를 사용할 때는
    //   사용하고 난 후 자원을 해제시는 close()를 반드시 호출하라.
    //
    System.out.println("데이터 출력 완료!");

  }

}

// 파일 입출력 API 주요 클래스 (java.io 패키지)
// 1) 데이터 읽기
// InputStream (추상 클래스)
//   +-- FileInputStream : 바이트 단위로 읽기 (binary stream)
//
// Reader (추상 클래스)
//   +-- FileReader : 문자 단위로 읽기 (character stream)
//
// 2) 데이터 쓰기
// OutputStream (추상 클래스)
//   +-- FileOutputStream : 바이트 단위로 쓰기 (binary stream)
//
// Writer (추상 클래스)
//   +-- FileWriter : 문자 단위로 쓰기 (character stream)

// ## 바이너리 파일 vs 텍스트 파일
// 1) 바이너리 파일
// - character set(문자표) 규칙에 따라 작성한 파일이 아닌 파일.
// - 기본 텍스트 편집기(메모장, vi 에디터 등)로 편집할 수 없는 파일을 말한다.
// - 만약 텍스트 편집기로 변경한 후 저장하면, 파일 포맷이 깨지기 때문에 무효한 파일이 된다.
// - 예) .pdf, .ppt, .xls, .gif, .mp3, .jpg, .hwp, .mov, .avi, .exe, .lib 등
// - 바이너리 파일을 편집하려면 해당 파일 포맷을 이해하는 전용 프로그램이 필요하다.
//
// 2) 텍스트 파일
// - 특정 character set(문자표) 규칙에 따라 작성한 파일.
// - 기본 텍스트 편집기(메모장, vi 에디터 등)로 편집할 수 있는 파일을 말한다.
// - 예) .txt, .csv, .html, .js, .css, .xml, .bat, .c, .py, .php, .docx, .pptx, .xlsx 등
// - 텍스트 파일은 전용 에디터가 필요 없다.
// - 텍스트를 편집할 수 있는 에디터라면 편집 후 저장해도 유효하다.

// 바이너리 데이터 읽고, 쓰기
// - 읽고 쓸 때 중간에서 변환하는 것 없이 바이트 단위로 그대로 읽고 써야 한다.
// - InputStream/OutputStream 계열의 클래스를 사용하라.
//
// 텍스트 데이터 읽고, 쓰기
// - 읽고 쓸 때 중간에서 문자 코드표에 따라 변환하는 것이 필요하다.
// - Reader/Writer 계열의 클래스를 사용하라.

 

 

Byte Stream - 바이트 단위로 읽기
package com.eomcs.io.ex02;

import java.io.FileInputStream;

public class Exam0120 {

  public static void main(String[] args) throws Exception {
    // 1) 파일 데이터 읽기를 담당할 객체를 준비한다.
    // - new FileInputStream(파일경로)
    // - 해당 경로에 파일이 존재하지 않으면 예외가 발생한다.
    //
    FileInputStream in = new FileInputStream("temp/test1.data");

    // 2) 1바이트를 읽는다.
    // => read() 메서드의 리턴 타입이 int 라 하더라도 1바이트를 읽어 리턴한다.
    // => 이유?
    //    0 ~ 255까지의 값을 읽기 때문이다.
    //    byte는 -128 ~ 127까지의 값만 저장한다.
    int b = in.read(); // 읽은 값은 0x4d 이다.
    System.out.printf("%02x\n", b);

    System.out.printf("%02x\n", in.read());
    System.out.printf("%02x\n", in.read());
    System.out.printf("%02x\n", in.read());
    // read() 를 호출할 때마다 이전에 읽은 바이트의 다음 바이트를 읽는다. 

    // 3) 읽기 도구를 닫는다.
    in.close();
  }
}

 

 

Byte Stream - 바이트 단위로 읽기 II
package com.eomcs.io.ex02;

import java.io.FileInputStream;

public class Exam0130 {

  public static void main(String[] args) throws Exception {
    FileInputStream in = new FileInputStream("temp/test1.data");

    // 반복문을 이용하여 여러 바이트를 읽는다.
    int b;
    //    while (true) {
    //      b = in.read();
    //      if (b == -1) // 파일의 끝에 도달하면 -1을 리턴한다.
    //        break;
    //      System.out.printf("%02x ", b);
    //    }

    while ((b = in.read()) != -1) {
      System.out.printf("%02x ", b);
    }

    in.close();
  }
}

 

 

Byte Stream - 바이트 배열 출력하기
package com.eomcs.io.ex02;

import java.io.FileOutputStream;

public class Exam0210 {

  public static void main(String[] args) throws Exception {

    // 현재 디렉토리는 프로젝트 폴더이다.
    //
    FileOutputStream out = new FileOutputStream("temp/test1.data");

    byte[] bytes = {0x7a, 0x6b, 0x5c, 0x4d, 0x3e, 0x2f, 0x30};

    // write(byte[]) : 배열의 값 전체를 출력한다.
    // write(byte[], 시작인덱스, 출력개수) : 시작 위치부터 지정된 개수를 출력한다.
    //
    out.write(bytes); // 바이트 배열 전체를 출력한다.

    out.close();

    System.out.println("데이터 출력 완료!");

  }

}

 

 

Byte Stream - 바이트 배열 읽기
package com.eomcs.io.ex02;

import java.io.FileInputStream;

public class Exam0220 {

  public static void main(String[] args) throws Exception {

    FileInputStream in = new FileInputStream("temp/test1.data");

    // 바이트들을 저장할 배열을 넉넉히 준비한다.
    // => 이렇게 임시 데이터를 저장하기 위해 만든 바이트 배열을 보통 "버퍼(buffer)"라 한다.
    //
    byte[] buf = new byte[100];

    // read(byte[])
    // - 버퍼가 꽉 찰 때까지 읽는다.
    // - 물론 버퍼 크기보다 파일의 데이터가 적으면 파일을 모두 읽어 버퍼에 저장한다.
    // - 리턴 값은 읽은 바이트의 개수이다.
    // read(byte[], 저장할 위치, 저장하기를 희망하는 개수)
    // - 읽은 데이터를 "저장할 위치"에 지정된 방부터 개수만큼 저장한다.
    // - 리턴 값은 실제 읽은 바이트 개수이다.
    int count = in.read(buf);

    in.close();

    System.out.printf("읽은 바이트 수: %d\n", count);

    for (int i = 0; i < count; i++)
      System.out.printf("%02x ", buf[i]);

    System.out.println();
  }
}

 

 

Byte Stream - 바이트 배열의 특정 부분을 출력하기
package com.eomcs.io.ex02;

import java.io.FileOutputStream;

public class Exam0310 {

  public static void main(String[] args) throws Exception {
    FileOutputStream out = new FileOutputStream("temp/test1.data");

    byte[] bytes = {0x7a, 0x6b, 0x5c, 0x4d, 0x3e, 0x2f, 0x30};

    // write(byte[]) : 배열의 값 전체를 출력한다.
    // write(byte[], 시작인덱스, 출력개수) : 시작 위치부터 지정된 개수를 출력한다.
    //
    out.write(bytes, 2, 3); // 2번 데이터부터 3 바이트를 출력한다.

    out.close();

    System.out.println("데이터 출력 완료!");
  }
}

 

 

Byte Stream - 읽은 데이터를 바이트 배열의 특정 위치에 저장하기
package com.eomcs.io.ex02;

import java.io.FileInputStream;

public class Exam0320 {

  public static void main(String[] args) throws Exception {
    FileInputStream in = new FileInputStream("temp/test1.data");

    // 데이터를 저장할 바이트 배열을 준비한다.
    byte[] buf = new byte[100];

    // 바이너리 데이터를 읽어 배열에 저장하기
    // read(byte[])
    //   => 읽은 데이터를 바이트 배열에 채운다.
    //   => 리턴 값은 읽은 바이트 수이다.
    // read(byte[], 저장할 위치, 저장하기를 희망하는 개수)
    //   => 읽은 데이터를 "저장할 위치"에 지정된 방부터 개수만큼 저장한다.
    //   => 리턴 값은 실제 읽은 바이트 개수이다.
    int count = in.read(buf, 10, 40); // 40바이트를 읽어 10번 방부터 저장한다.

    in.close();

    System.out.printf("%d\n", count);

    for (int i = 0; i < 100; i++)
      System.out.printf("%d: %02x \n", i, buf[i]);

    System.out.println();
  }
}

 

 

FileInputStream 활용 - JPEG 파일 읽기
package com.eomcs.io.ex02;

import java.io.File;
import java.io.FileInputStream;

public class Exam0410 {

  public static void main(String[] args) throws Exception {

    // 1) 파일 정보를 준비한다.
    File file = new File("sample/photo1.jpg");

    // 2) 파일을 읽을 도구를 준비한다.
    FileInputStream in = new FileInputStream(file);

    // => SOI(Start of Image) Segment 읽기: 2바이트
    int b1 = in.read(); // 00 00 00 ff
    int b2 = in.read(); // 00 00 00 d8
    int soi = b1 << 8 | b2;
    //   00 00 00 ff <== b1
    //   00 00 ff 00 <== b1 << 8
    // | 00 00 00 d8 <== b2
    // ------------------
    //   00 00 ff d8
    System.out.printf("SOI: %x\n", soi);

    // => JFIF-APP0 Segment Marker 읽기: 2바이트
    int jfifApp0Marker = in.read() << 8 | in.read();
    System.out.printf("JFIF APP0 Marker: %x\n", jfifApp0Marker);

    // => JFIF-APP0 Length: 2바이트
    int jfifApp0Length = in.read() << 8 | in.read();
    System.out.printf("JFIF APP0 정보 길이: %d\n", jfifApp0Length);

    // => JFIF-APP0 정보: 16바이트(위에서 알아낸 길이)
    byte[] jfifApp0Info = new byte[jfifApp0Length];
    in.read(jfifApp0Info);

    // => JFIF-APP0 Identifier: 5바이트
    String jfifApp0Id = new String(jfifApp0Info, 0, 4);
    System.out.printf("JFIF APP0 ID: %s\n", jfifApp0Id);

    // SOF0(Start of Frame) 정보 읽기
    // - 그림 이미지의 크기 및 샘플링에 관한 정보를 보관하고 있다
    // - 0xFFC0 ~ 0xFFC2 로 표시한다.

    // => SOF Marker 찾기
    int b;
    while (true) {
      b = in.read();
      if (b == -1) { // 파일 끝에 도달
        break;
      }

      if (b == 0xFF) {
        b = in.read();
        if (b == -1) { // 파일 끝에 도달
          break;
        }
        if (b >= 0xC0 && b <= 0xC2) {
          break;
        }
      }
    }

    if (b == -1) {
      System.out.println("유효한 JPEG 파일이 아닙니다.");
      return;
    }

    // => SOF Length 읽기: 2바이트
    int sofLength = in.read() << 9 | in.read();
    System.out.printf("SOF 데이터 크기: %d\n", sofLength);

    // => SOF 데이터 읽기: 17바이트(위에서 알아낸 크기)
    byte[] sofData = new byte[sofLength];
    in.read(sofData);

    // => SOF 샘플링 정밀도: 1바이트
    System.out.printf("SOF 샘플링 정밀도: %d\n", sofData[0]);

    // => SOF 이미지 높이: 2바이트
    int height = ((sofData[1] << 8) & 0xff00) | (sofData[2] & 0xff);

    // => SOF 이미지 너비: 2바이트
    int width = ((sofData[3] << 8) & 0xff00) | (sofData[4] & 0xff);
    System.out.printf("SOF 이미지 크기(w x h): %d x %d\n", width, height);


    // 3) 읽기 도구를 닫는다.
    in.close();
  }

}

 

 

Byte Stream - 텍스트 출력 하기
package com.eomcs.io.ex02;

import java.io.FileOutputStream;

public class Exam0510 {

  public static void main(String[] args) throws Exception {

    String str = new String("AB가각");

    // String 객체의 데이터를 출력하려면
    // 문자열을 담은 byte[] 배열을 리턴 받아야 한다.

    // String.getBytes()
    // => 특정 인코딩을 지정하지 않고 그냥 바이트 배열을 달라고 하면,
    //    String 클래스는 JVM 환경 변수 'file.encoding' 에 설정된 문자집합으로 
    //    바이트 배열을 인코딩 한다.  
    // => 이클립스에서 애플리케이션을 실행할 때 다음과 같이 JVM 환경변수를 자동으로 붙인다. 
    //      $ java -Dfile.encoding=UTF-8 .... 
    // => 그래서 getBytes()가 리턴한 바이트 배열의 인코딩은 UTF-8이 되는 것이다.
    // => 만약 이 예제를 이클립스가 아니라 콘솔창에서 
    //    -Dfile.encoding=UTF-8 옵션 없이 실행한다면,
    //    getBytes()가 리턴하는 바이트 배열은
    //    OS의 기본 인코딩으로 변환될 것이다.
    // => OS 기본 인코딩 
    //      Windows => MS949
    //      Linux/macOS => UTF-8
    // => OS에 상관없이 동일한 실행 결과를 얻고 싶다면, 다음과 같이 file.encoding 옵션을 붙여라
    //      $ java -Dfile.encoding=UTF-8 -cp bin/main .....
    // => 또는 getBytes() 호출할 때 인코딩할 문자집합을 지정하라.
    //      str.getBytes("UTF-8")
    //
    // JVM에 문자를 입출력할 때 사용하는 기본 문자 집합이 무엇인지 알아 본다.
    System.out.printf("file.encoding=%s\n", System.getProperty("file.encoding"));
    byte[] bytes = str.getBytes();  // 문자집합을 지정하지 않으면 file.encoding에 설정된 문자집합으로 인코딩하여 리턴한다.
    //
    // 이클립스: 
    //      UCS2 ==> UTF-8
    //      이클립스의 경우 자바 앱을 실행할 때 file.encoding 변수의 값을 utf-8 로 설정한다.
    // 
    // file.encoding JVM 환경 변수의 값이 설정되어 있지 않을 경우, 
    //      Windows: UCS2 ==> MS949
    //      Linux: UCS2 ==> UTF-8
    //      macOS: UCS2 ==> UTF-8
    //
    for (byte b : bytes) {
      System.out.printf("%x ", b);
    }
    System.out.println();

    // 바이트 배열 전체를 그대로 출력한다.
    FileOutputStream out = new FileOutputStream("temp/utf.txt");
    out.write(bytes);
    out.close();
    System.out.println("데이터 출력 완료!");
  }

}

 

package com.eomcs.io.ex02;

import java.io.FileOutputStream;

public class Exam0512 {

  public static void main(String[] args) throws Exception {

    String str = new String("AB가각");

    // String 객체의 데이터를 출력하려면
    // 문자열을 담은 byte[] 배열을 리턴 받아야 한다.

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

    for (byte b : bytes) {
      System.out.printf("%02x ", b);
    }
    System.out.println();

    // 바이트 배열 전체를 그대로 출력한다.
    FileOutputStream out = new FileOutputStream("temp/utf16be.txt");
    out.write(bytes);
    out.close();
    System.out.println("데이터 출력 완료!");
  }

}

 

package com.eomcs.io.ex02;

import java.io.FileOutputStream;

public class Exam0513 {

  public static void main(String[] args) throws Exception {

    String str = new String("AB가각");

    // String 객체의 데이터를 출력하려면
    // 문자열을 담은 byte[] 배열을 리턴 받아야 한다.

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

    for (byte b : bytes) {
      System.out.printf("%02x ", b);
    }
    System.out.println();

    // 바이트 배열 전체를 그대로 출력한다.
    FileOutputStream out = new FileOutputStream("temp/utf16le.txt");
    out.write(bytes);
    out.close();
    System.out.println("데이터 출력 완료!");
  }

}

 

package com.eomcs.io.ex02;

import java.io.FileOutputStream;

public class Exam0514 {

  public static void main(String[] args) throws Exception {

    String str = new String("AB가각");

    // String 객체의 데이터를 출력하려면
    // 문자열을 담은 byte[] 배열을 리턴 받아야 한다.

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

    for (byte b : bytes) {
      System.out.printf("%x ", b);
    }
    System.out.println();

    // 바이트 배열 전체를 그대로 출력한다.
    FileOutputStream out = new FileOutputStream("temp/utf8.txt");
    out.write(bytes);
    out.close();
    System.out.println("데이터 출력 완료!");
  }

}

 

 

Byte Stream - 텍스트 데이터 읽기
package com.eomcs.io.ex02;

import java.io.FileInputStream;

public class Exam0520 {

  public static void main(String[] args) throws Exception {
    FileInputStream in = new FileInputStream("sample/ms949.txt");

    int b = 0;

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

    }

    in.close();
  }

}

 

 

Byte Stream - 텍스트 데이터 읽기 II
package com.eomcs.io.ex02;

import java.io.FileInputStream;

public class Exam0521 {

  public static void main(String[] args) throws Exception {
    // 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 객체로 만들어보자.
    // - 바이트 배열에 저장된 문자 코드를
    //   JVM이 사용하는 문자 집합(UCS2=UTF16BE)의 코드 값으로 변환한다.
    // - 바이트 배열에 들어 있는 코드 값이 어떤 문자 집합의 값인지 알려주지 않는다면,
    //   JVM 환경 변수 file.encoding에 설정된 문자 집합으로 가정하고 변환을 수행한다.
    String str = new String(buf, 0, count);  // new String(buf) 가능

    // 바이트 배열이 어떤 문자집합으로 인코딩 된 것인지 알려주지 않으면,
    // file.encoding에 설정된 문자집합으로 인코딩된 것으로 간주한다.

    System.out.println(str);

    // 바이트가 어떤 문자 집합으로 인코딩 되었는지 알려주지 않는다면?
    // String 객체를 생성할 때 다음의 규칙에 따라 변환한다.
    // => JVM 환경 변수 'file.encoding' 에 설정된 문자집합으로 가정하고 UCS2 문자 코드로 변환한다.
    //
    // 1) 이클립스에서 실행 => 성공!
    // - JVM 실행 옵션에 '-Dfile.encoding=UTF-8' 환경 변수가 자동으로 붙는다.
    // - 그래서 String 클래스는 바이트 배열의 값을 UCS2로 바꿀 때 UTF-8 문자표를 사용하여 UCS2 로 변환한다.
    // - 예1)
    //   utf8.txt  => 41 42 ea b0 80 ea b0 81
    //   UCS2      => 0041 0042 ac00 ac01  <== 정상적으로 바뀐다.
    //
    // 2) Windows 콘솔에서 실행 => 실패!
    // - JVM을 실행할 때 file.encoding을 설정하지 않으면
    //   OS의 기본 문자집합으로 설정한다.
    // - Windows의 기본 문자집합은 MS949 이다.
    // - 따라서 file.encoding 값은 MS949가 된다.
    // - 바이트 배열은 UTF-8로 인코딩 되었는데,
    //   MS949 문자표를 사용하여 UCS2로 변환하려 하니까
    //   잘못된 문자로 변환되는 것이다.
    // - 해결책?
    //   JVM을 실행할 때 file.encoding 옵션에 정확하게 해당 파일의 인코딩을 설정하라.
    //   즉 utf8.txt 파일은 UTF-8로 인코딩 되었기 때문에
    //     '-Dfile.encoding=UTF-8' 옵션을 붙여서 실행해야 UCS2로 정상 변환된다.
    //
    // 3) Linux/macOS 콘솔에서 실행 => 성공!
    // - Linux와 macOS의 기본 문자 집합은 UTF-8이다.
    // - 따라서 JVM을 실행할 때 '-Dfile.encoding=UTF-8' 옵션을 지정하지 않아도
    //   해당 파일을 UTF-8 문자로 간주하여 UTF-8 문자표에 따라 UCS2로 변환한다.
    //
  }

}

 

package com.eomcs.io.ex02;

import java.io.FileInputStream;

public class Exam0522 {

  public static void main(String[] args) throws Exception {
    // JVM 환경 변수 'file.encoding' 값
    System.out.printf("file.encoding=%s\n", System.getProperty("file.encoding"));

    FileInputStream in = new FileInputStream("sample/ms949.txt"); // 41 42 b0 a1 b0 a2(AB가각)

    // 파일의 데이터를 한 번에 읽어보자.
    byte[] buf = new byte[1000];
    int count = in.read(buf);

    in.close();

    String str = new String(buf, 0, count);
    // 바이트 배열에 MS949 문자집합에 따라 인코딩 된 데이터가 들어 있는데,
    // String 클래스는 UTF-8 문자집합으로 인코딩 되었다고 가정하기 때문에
    // UTF-16으로 정확하게 변환할 수 없는 것이다.

    System.out.println(str);

    // ms949.txt 파일을 읽을 때 문자가 깨지는 이유?
    // - 한글이 다음과 같이 MS949 문자 집합으로 인코딩 되어 있다.
    //      ms949.txt => 41 42 b0 a1 b0 a2
    // - String 객체를 생성할 때 바이트 배열의 문자집합을 알려주지 않으면 
    //   JVM 환경 변수 'file.encoding'에 설정된 문자집합이라고 가정한다.
    // 
    // 1) 이클립스에서 실행 => 실패!
    // - 이클립스에서  JVM을 실행할 때 '-Dfile.encoding=UTF-8' 옵션을 붙인다.
    // - 따라서 String 클래스는 바이트 배열의 값을 UCS2로 변환할 때 UTF-8 문자표를 사용한다.
    // - 문제는, 바이트 배열의 값이 MS949로 인코딩 되어 있다는 사실이다.
    //   즉 잘못된 문자표를 사용하니까 변환을 잘못한 것이다.
    //
    // 2) Windows 콘솔에서 실행 => 성공!
    // - JVM을 실행할 때 'file.encoding' 환경 변수를 지정하지 않으면,
    //   OS의 기본 문자 집합으로 설정한다.
    // - Windows의 기본 문자 집합은 MS949이다.
    // - 따라서 file.encoding의 값은 MS949로 설정된다.
    // - 바이트 배열의 값이 MS949 이기 때문에 MS949 문자표로 변환하면 
    //   UCS2 문자 코드로 잘 변환되는 것이다.
    //
    // MS949 코드를 UTF-8 문자로 가정하고 다룰 때 한글이 깨지는 원리! 
    // - ms949.txt 
    //   => 01000001 01000010 10110000 10100001 10110000 10100010 = 41 42 b0 a1 b0 a2
    // - MS949 코드를 변환할 때 UTF-8 문자표를 사용하면 다음과 같이 잘못된 변환을 수행한다.
    //   byte(UTF-8) => char(UCS2) 
    //     01000001  -> 00000000 01000001 (00 41) = 'A' <-- 정상적으로 변환되었음.
    //     01000010  -> 00000000 01000010 (00 42) = 'B' <-- 정상적으로 변환되었음.
    //     10110000  -> 꽝 (xx xx) <-- 해당 바이트가 UTF-8 코드 값이 아니기 때문에 UCS2로 변환할 수 없다.
    //     10100001  -> 꽝 (xx xx) <-- 그래서 꽝을 의미하는 특정 코드 값이 들어 갈 것이다.
    //     10110000  -> 꽝 (xx xx) <-- 그 코드 값을  문자로 출력하면 => �
    //     10100010  -> 꽝 (xx xx)
  }

}

 

package com.eomcs.io.ex02;

import java.io.FileInputStream;

public class Exam0523 {

  public static void main(String[] args) throws Exception {
    // JVM 환경 변수 'file.encoding' 값
    System.out.printf("file.encoding=%s\n", System.getProperty("file.encoding"));

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

    // 파일의 데이터를 한 번에 읽어보자.
    byte[] buf = new byte[1000];
    int count = in.read(buf);

    in.close();

    // JVM 환경 변수 'file.encoding'에 설정된 문자표에 상관없이 
    // String 객체를 만들 때 바이트 배열의 인코딩 문자 집합을 정확하게 알려준다면,
    //  UCS2 코드 값으로 정확하게 변환해 줄 것이다.
    String str = new String(buf, 0, count, "CP949"); // MS949 = CP949 
    System.out.println(str);
  }

}

 

package com.eomcs.io.ex02;

import java.io.FileInputStream;

public class Exam0524 {

  public static void main(String[] args) throws Exception {
    // JVM 환경 변수 'file.encoding' 값
    System.out.printf("file.encoding=%s\n", System.getProperty("file.encoding"));

    FileInputStream in = new FileInputStream("sample/utf16be.txt"); // 0041 0042 ac00 ac01(AB가각)

    // 파일의 데이터를 한 번에 읽어보자.
    byte[] buf = new byte[1000];
    int count = in.read(buf);

    in.close();

    // JVM 환경 변수 'file.encoding'에 설정된 문자표에 상관없이 
    // String 객체를 만들 때 바이트 배열의 인코딩 문자 집합을 정확하게 알려준다면,
    //  UCS2 코드 값으로 정확하게 변환해 줄 것이다.
    String str = new String(buf, 0, count, "UTF-16"); // UTF-16 == UTF-16BE
    System.out.println(str);
  }

}

 

package com.eomcs.io.ex02;

import java.io.FileInputStream;

public class Exam0525 {

  public static void main(String[] args) throws Exception {
    // JVM 환경 변수 'file.encoding' 값
    System.out.printf("file.encoding=%s\n", System.getProperty("file.encoding"));

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

    // 파일의 데이터를 한 번에 읽어보자.
    byte[] buf = new byte[1000];
    int count = in.read(buf);

    in.close();

    // JVM 환경 변수 'file.encoding'에 설정된 문자표에 상관없이 
    // String 객체를 만들 때 바이트 배열의 인코딩 문자 집합을 정확하게 알려준다면,
    //  UCS2 코드 값으로 정확하게 변환해 줄 것이다.
    String str = new String(buf, 0, count, "UTF-16LE");
    System.out.println(str);
  }

}

 

 

com.eomcs.io.ex03

 

 

character stream - 문자 단위로 출력하기
package com.eomcs.io.ex03;

import java.io.FileWriter;

public class Exam0110 {
  public static void main(String[] args) throws Exception {

    // JVM의 문자열을 파일로 출력할 때
    // FileOutputStream 과 같은 바이트 스트림 클래스를 사용하면
    // 문자집합을 지정해야 하는 번거로움이 있었다.
    // => 이런 번거로움을 해결하기 위해 만든 스트림 클래스가 있으니,
    //    문자 스트림 클래스이다.
    // => 즉 Reader/Writer 계열의 클래스이다.

    // 1) 문자 단위로 출력할 도구 준비
    FileWriter out = new FileWriter("temp/test2.txt");

    // 2) 문자 출력하기
    // - JVM은 문자 데이터를 다룰 때 UCS2(UTF16BE, 2바이트) 유니코드를 사용한다.
    // - character stream 클래스 FileWriter는 문자 데이터를 출력할 때
    //   UCS2 코드를 JVM 환경변수 file.encoding 에 설정된 character set 코드로 변환하여 출력한다.
    // - JVM을 실행할 때 -Dfile.encoding=문자집합 옵션으로 기본 문자 집합을 설정한다. 
    //   만약 file.encoding 옵션을 설정하지 않으면 OS의 기본 문자집합으로 자동 설정된다.
    // 
    //   Linux, macOS 의 기본 character set => UTF-8
    //   Windows 의 기본 character set => MS-949
    // 
    // - file.encoding 옵션을 설정하지 않은 상태에서는 
    //   어느 OS에서 실행하느냐에 따라 출력되는 코드 값이 달라진다.
    // 
    // - 이클립스에서 실행할 경우, 
    //   이클립스가 file.encoding 옵션의 문자집합을 UTF-8로 설정한다.
    // 
    // - 명령창(콘솔창)에서 실행한다면,
    //   위에서 설명한대로 OS에 따라 다르게 인코딩 된다.
    //
    // - OS에 상관없이 동일한 character set으로 출력하고 싶다면
    //   JVM을 실행할 때 file.encoding 프로퍼티에 character set 이름을 지정하라.
    //
    // - JVM을 실행할 때 출력 데이터의 문자 코드표를 지정하는 방법
    //       java -Dfile.encoding=문자코드표 -cp 클래스경로 클래스명
    //   예) java -Dfile.encoding=UTF-8 -cp bin/main com.eomcs.io.ex03.Exam0110
    //
    // - 단, character set을 지정할 때는 해당 OS에서 사용가능한 문자표이어야 한다.
    //   MS Windows에서는 ms949 문자표를 사용할 수 있지만,
    //   리눅스나 macOS에서는 ms949 문자표를 사용할 수 없다.
    //   왜?
    //   국제 표준이 아니기 때문이다.
    //
    // [이클립스에서 실행]
    // - JVM을 실행할 때 '-Dfile.encoding=UTF-8' 옵션을 자동으로 붙인다.
    // - 그래서 출력할 때, UCS2를 UTF-8 코드로 변환하여 파일에 쓴다.
    //
    // [콘솔창에서 실행]
    // 1) file.encoding 환경 변수를 지정하지 않으면,
    // - OS가 기본으로 사용하는 문자 코드로 변환하여 파일에 쓴다.
    // - windows : MS949
    // - linux/unix/macOS : UTF-8
    //
    // 2) JVM을 실행할 때 '-Dfile.encoding=문자코드표' 옵션을 지정한다면,
    // - 해당 옵션에 지정된 문자 코드로 변환하여 파일에 쓴다.
    //
    // [결론]
    // - OS에 영향 받지 않으려면,
    //   JVM을 실행할 때 반드시 file.encoding JVM 환경 변수를 설정하라.
    // - 문자집합은 UTF-8을 사용하라.
    //   - 국제 표준이다.
    //   - linux, macOS의 기본 문자 집합이다.
    //

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

    // => 이 예제를 이클립스에서 실행한다면,
    // 앞의 2바이트는 버리고,
    // 뒤의 2바이트(UCS2)를 UTF-8 코드표에 따라
    // 1 ~ 4 바이트 값으로 변환하여 파일에 쓴다.
    // => 즉 이클립스에서 자바 프로그램을 실행할 때
    //    -Dfile.encoding=UTF-8 옵션을 붙여 실행하기 때문이다.
    // => OS의 기본 문자표로 출력하고 싶다면,
    //    콘솔창에서 위 옵션 없이 직접 이 클래스를 실행하라.
    //
    // UCS2에서 한글 '가'는 ac00이다.
    out.write(0x7a6bac00);
    // - 앞의 2바이트(7a6b)는 버린다.
    // - 뒤의 2바이트(ac00)은 UTF-8(eab080) 코드 값으로 변환되어 파일에 출력된다.

    // UCS2에서 영어 A는 0041이다.
    // 출력하면, UTF-8 코드 값(41)이 파일에 출력된다.
    out.write(0x7a5f0041);  //
    // - 앞의 2바이트(7a5f)는 버린다.
    // - 뒤의 2바이트(0041)는 UTF-8(41) 코드 값으로 변환되어 파일에 출력된다.

    out.close();

    System.out.println("출력 완료!");

  }
}

 

 

character stream - 출력할 문자 집합 설정하기
package com.eomcs.io.ex03;

import java.io.FileWriter;
import java.nio.charset.Charset;

public class Exam0111 {
  public static void main(String[] args) throws Exception {

    System.out.println(Charset.isSupported("EUC-KR"));

    // 1) 출력 스트림 객체를 생성할 때  문자 집합을 지정하면 
    //    UCS2 문자열을 해당 문자집합으로 인코딩 한다.
    Charset charset = Charset.forName("EUC-KR");
    FileWriter out = new FileWriter("temp/test2.txt", charset);

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

    // UCS2에서 한글 '가'는 ac00이다.
    out.write(0x7a6bac00); 
    // - 앞의 2바이트(7a6b)는 버린다.
    // - 뒤의 2바이트(ac00)은 MS949(b0a1) 코드 값으로 변환되어 파일에 출력된다.

    // UCS2에서 영어 'A'는 0041이다.
    out.write(0x7a5f0041);  // 
    // - 앞의 2바이트(7a5f)는 버린다.
    // - 뒤의 2바이트는 MS949(41) 코드 값으로 변환되어 파일에 출력된다.

    out.close();

    System.out.println("출력 완료!");

  }
}

 

 

package com.eomcs.io.ex03;

import java.io.FileWriter;
import java.nio.charset.Charset;

public class Exam0112 {
  public static void main(String[] args) throws Exception {


    // 1) 출력 스트림 객체를 생성할 때  문자 집합을 지정하면 
    //    UCS2 문자열을 해당 문자집합으로 인코딩 한다.
    Charset charset = Charset.forName("UTF-16BE");
    FileWriter out = new FileWriter("temp/test2.txt", charset);

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

    // UCS2에서 한글 '가'는 ac00이다.
    out.write(0x7a6bac00); 
    // - 앞의 2바이트(7a6b)는 버린다.
    // - 뒤의 2바이트(ac00)은 UTF-16BE(ac00) 코드 값으로 변환되어 파일에 출력된다.

    // UCS2에서 영어 'A'는 0041이다.
    out.write(0x7a5f0041);  // 
    // - 앞의 2바이트(7a5f)는 버린다.
    // - 뒤의 2바이트는 UTF-16BE(0041) 코드 값으로 변환되어 파일에 출력된다.

    out.close();

    System.out.println("출력 완료!");

  }
}

 

 

character stream - 문자 단위로 읽기
package com.eomcs.io.ex03;

import java.io.FileReader;

public class Exam0120 {

  public static void main(String[] args) throws Exception {

    // 1) 파일의 데이터를 읽는 일을 하는 객체를 준비한다.
    FileReader in = new FileReader("sample/utf8.txt"); // 41 42 ea b0 81 ea b0 81

    // 2) JVM 환경 변수 'file.encoding'에 설정된 문자코드표에 따라
    //    바이트를 읽어서 UCS2로 바꾼 후에 리턴한다.
    //
    // - JVM을 실행할 때 다음 옵션을 지정하지 않으면
    //     -Dfile.encoding=문자표
    // - JVM은 OS의 기본 문자표라고 가정하고 파일을 읽는다.
    //   만약 이클립스에서 실행한다면,
    //   UTF-8이라고 가정하고 읽는다.
    //   만약 명령창(콘솔창)에서 실행한다면,
    //   OS에 따라 다르게 읽는다.
    //
    // 현재 JVM 환경 변수 'file.encoding' 값 알아내기
    System.out.printf("file.encoding=%s\n", System.getProperty("file.encoding"));

    // file.encoding이 UTF-8로 되어 있다면,
    // => 영어는 1바이트를 읽어서 2바이트 UCS2로 변환한다.
    int ch1 = in.read(); // 41 => 0041('A')
    int ch2 = in.read(); // 42 => 0042('B')

    // => 한글은 3바이를 읽어서 2바이트 UCS2로 변환한다.
    int ch3 = in.read(); // ea b0 80 => ac00('가')
    int ch4 = in.read(); // ea b0 81 => ac01('각')

    // 3) 읽기 도구를 닫는다.
    in.close();

    System.out.printf("%04x, %04x, %04x, %04x\n", ch1, ch2, ch3, ch4);
  }
}

 

 

package com.eomcs.io.ex03;

import java.io.FileReader;

public class Exam0122 {

  public static void main(String[] args) throws Exception {
    // 1) 파일의 데이터를 읽을 객체를 준비한다.
    FileReader in = new FileReader("sample/ms949.txt"); // 41 42 b0 a1 b0 a2

    // 2) 출력 스트림 객체를 생성할 때 파일의 문자 집합을 지정하지 않으면,
    //    JVM 환경 변수 'file.encoding'에 설정된 문자코드표에 따라
    //    바이트를 읽어서 UCS2로 바꾼 후에 리턴한다.

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

    // file.encoding이 UTF-8로 되어 있다면,
    // => 영어는 1바이트를 읽어서 2바이트 UCS2로 변환한다.
    // => MS949도 영어인 경우 UTF-8과 같기 때문에 변환하는데 문제가 없다.
    int ch1 = in.read(); // 41 => 0041('A')
    int ch2 = in.read(); // 42 => 0042('B')

    // => 한글은 MS949와 UTF-8이 다르다.
    //    MS949로 인코딩 된 것을 UTF-8로 간주하여 변환한다면,
    //    UTF-8 문자가 아니기 때문에
    //    다음과 같이 잘못되었다는 의미로 특정 값(fffd)으로 변환한다.
    int ch3 = in.read(); // b0 a1 => fffd => �
    int ch4 = in.read(); // b0 a2 => fffd => �

    // 3) 읽기 도구를 닫는다.
    in.close();

    System.out.printf("%04x, %04x, %04x, %04x\n", ch1, ch2, ch3, ch4);
  }
}

 

 

package com.eomcs.io.ex03;

import java.io.FileReader;
import java.nio.charset.Charset;

public class Exam0123 {

  public static void main(String[] args) throws Exception {
    // 1) 파일의 데이터를 읽을 객체를 준비한다. 
    // => 읽어들일 파일의 문자집합이 file.encoding 환경변수에 지정된 값과 다르다면,
    //    다음과 같이 출력 스트림을 생성할 때 파일의 문자집합을 알려줘라.
    FileReader in = new FileReader("sample/ms949.txt", Charset.forName("MS949")); // 41 42 b0 a1 b0 a2

    // 2) 출력 스트림 객체를 생성할 때 파일의 문자 집합을 지정하면,
    //    JVM 환경 변수 'file.encoding'에 설정된 문자집합을 무시한다.

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

    // file.encoding이 UTF-8로 설정되어 있지만,
    // 출력 스트림에 'MS949'를 사용한다고 했기 때문에 
    // MS949 문자표에 따라 UCS2로 변환할 것이다.
    int ch1 = in.read(); // 41 => 0041('A')
    int ch2 = in.read(); // 42 => 0042('B')

    // 한글
    int ch3 = in.read(); // b0 a1 => ac00 => '가'
    int ch4 = in.read(); // b0 a2 => ac01 => '각'

    // 3) 읽기 도구를 닫는다.
    in.close();

    System.out.printf("%04x, %04x, %04x, %04x\n", ch1, ch2, ch3, ch4);
  }
}

 

 

Character Stream - 문자 배열 출력하기
package com.eomcs.io.ex03;

import java.io.FileWriter;

public class Exam0210 {

  public static void main(String[] args) throws Exception {
    FileWriter out = new FileWriter("temp/test2.txt");

    char[] chars = new char[] {'A', 'B', 'C', '0', '1', '2', '가', '각', '간', '똘', '똥'};

    // FileOutputStream 은 byte[] 을 출력하지만,
    // FileWriter 는 char[] 을 출력한다.
    out.write(chars); // 문자 배열 전체를 출력한다.

    // 당연히 UCS2를 JVM 환경 변수 'file.encoding'에 설정된 문자 코드표에 따라 변환하여 출력한다.
    // JVM이 입출력 문자 코드표로 UTF-8을 사용한다면
    // 영어는 1바이트로 변환되어 출력될 것이고,
    // 한글은 3바이트로 변환되어 출력될 것이다.
    // JVM(UCS2)    File(UTF-8)
    // 00 41    ==> 41
    // 00 42    ==> 42
    // 00 43    ==> 43
    // 00 30    ==> 30
    // 00 31    ==> 31
    // 00 32    ==> 32
    // ac 00    ==> ea b0 80
    // ac 01    ==> ea b0 81
    // ac 04    ==> ea b0 84
    // b6 18    ==> eb 98 98
    // b6 25    ==> eb 98 a5
    out.close();

    System.out.println("데이터 출력 완료!");

  }

}

 

 

Character Stream - 문자 배열 읽기
package com.eomcs.io.ex03;

import java.io.FileReader;

public class Exam0220 {

  public static void main(String[] args) throws Exception {
    FileReader in = new FileReader("temp/test2.txt");

    // UCS2 문자 코드 값을 저장할 배열을 준비한다.
    // => 이렇게 임시 데이터를 저장하기 위해 만든 바이트 배열을 보통 "버퍼(buffer)"라 한다.
    char[] buf = new char[100];

    // read(버퍼의주소)
    // => 버퍼가 꽉 찰 때까지 읽는다.
    // => 물론 버퍼 크기보다 파일의 데이터가 적으면 파일을 모두 읽어 버퍼에 저장한다.
    // => 리턴 값은 읽은 문자의 개수이다. 바이트의 개수가 아니다!!!!!
    //    FileInputStream.read()의 리턴 값은 읽은 바이트의 개수였다.
    // => 파일을 읽을 때 JVM 환경 변수 'file.encoding'에 설정된 문자코드표에 따라 바이트를 읽는다.
    //    그리고 2바이트 UCS2 코드 값으로 변환하여 리턴한다.
    // => JVM의 문자코드표가 UTF-8이라면,
    //    파일을 읽을 때, 영어나 숫자, 특수기호는 1바이트를 읽어 UCS2으로 변환할 것이고
    //    한글은 3바이트를 읽어 UCS2으로 변환할 것이다.
    int count = in.read(buf);

    // File(UTF-8)  JVM(UCS2)
    // 41       ==> 00 41
    // 42       ==> 00 42
    // 43       ==> 00 43
    // 30       ==> 00 30
    // 31       ==> 00 31
    // 32       ==> 00 32
    // ea b0 80 ==> ac 00
    // ea b0 81 ==> ac 01
    // ea b0 84 ==> ac 04
    // eb 98 98 ==> b6 18
    // eb 98 a5 ==> b6 25

    in.close();

    System.out.printf("%d\n", count);
    for (int i = 0; i < count; i++)
      System.out.printf("%c(%04x)\n", buf[i], (int)buf[i]);

    System.out.println();

  }

}

 

 

Character Stream - char[] ==> String 변환하기
package com.eomcs.io.ex03;

import java.io.FileReader;

public class Exam0221 {

  public static void main(String[] args) throws Exception {
    FileReader in = new FileReader("temp/test2.txt");

    char[] buf = new char[100];

    int count = in.read(buf); // char 배열에 담을 때 UTF-16BE 코드 값으로 변환한다.
    String str = new String(buf, 0, count); // 그래서 String 객체를 만들 때 문자집합을 지정할 필요가 없다.

    in.close();

    System.out.printf("[%s]\n", str);
  }

}

 

 

Character Stream - 문자 배열의 특정 부분을 출력하기
package com.eomcs.io.ex03;

import java.io.FileWriter;

public class Exam0310 {

  public static void main(String[] args) throws Exception {
    FileWriter out = new FileWriter("temp/test2.txt");

    char[] chars = new char[] {'A','B','C','가','각','간','똘','똥'}; 

    out.write(chars, 2, 3); // 2번 문자부터 3 개의 문자를 출력한다.

    out.close();

    System.out.println("데이터 출력 완료!");

  }

}

 

 

Character Stream - 읽은 데이터를 문자 배열의 특정 위치에 저장하기
package com.eomcs.io.ex03;

import java.io.FileReader;

public class Exam0320 {

  public static void main(String[] args) throws Exception {
    FileReader in = new FileReader("temp/test2.txt");

    char[] buf = new char[100];

    // read(버퍼의주소, 저장할위치, 읽을바이트개수)
    // => 리턴 값은 실제 읽은 문자의 개수이다.
    int count = in.read(buf, 10, 40); // 40개의 문자를 읽어 10번 방부터 저장한다.

    in.close();

    System.out.printf("%d\n", count);

    for (int i = 0; i < 20; i++)
      System.out.printf("%c(%04x) ", buf[i], (int) buf[i]);

    System.out.println();

  }

}

 

 

Character Stream - String 출력하기
package com.eomcs.io.ex03;

import java.io.FileWriter;

public class Exam0410 {

  public static void main(String[] args) throws Exception {
    FileWriter out = new FileWriter("temp/test2.txt");

    String str = new String("AB가각");

    out.write(str); 

    out.close();

    System.out.println("데이터 출력 완료!");

  }

}

 

 

Character Stream - 텍스트 읽기
package com.eomcs.io.ex03;

import java.io.FileReader;
import java.nio.CharBuffer;

public class Exam0420 {

  public static void main(String[] args) throws Exception {
    FileReader in = new FileReader("temp/test2.txt");

    // FileReader 객체가 읽을 데이터를 저장할 메모리를 준비한다.
    CharBuffer charBuf = CharBuffer.allocate(100);

    // 읽은 데이터를 CharBuffer 에 저장한다.
    int count = in.read(charBuf);

    in.close();

    System.out.printf("%d\n", count);

    // 버퍼의 데이터를 꺼내기 전에 읽은 위치를 0으로 초기화시킨다.
    // - read() 메서드가 파일에서 데이터를 읽어서 버퍼에 채울 때 마다 커서의 위치는 다음으로 이동한다.
    // - 버퍼의 데이터를 읽으려면 커서의 위치를 처음으로 되돌려야 한다.(flip)
    // - flip() 메서드를 호출하여 커서를 처음으로 옮긴다. 그런 후에 버퍼의 텍스를 읽어야 한다.
    charBuf.flip();

    System.out.printf("[%s]\n", charBuf.toString());
  }

}

 

 

Character Stream - 텍스트 읽기 II
package com.eomcs.io.ex03;

import java.io.BufferedReader;
import java.io.FileReader;

public class Exam0430 {

  public static void main(String[] args) throws Exception {
    FileReader in = new FileReader("temp/test2.txt");

    // 데코레이터를 붙인다.
    // => 버퍼 기능 + 한 줄 읽기 기능
    BufferedReader in2 = new BufferedReader(in);

    System.out.println(in2.readLine());

    in.close();
  }

}

 

 

 

com.eomcs.io.ex04

 

 

데이터 출력 - int 값 출력
package com.eomcs.io.ex04;

import java.io.FileOutputStream;

public class Exam0110 {

  public static void main(String[] args) throws Exception {
    FileOutputStream out = new FileOutputStream("temp/test3.data");

    int money = 1_3456_7890; // = 0x080557d2

    out.write(money); //항상 출력할 때는 맨 끝 1바이트만 출력한다.

    out.close();

    System.out.println("데이터 출력 완료!");

  }

}

 

 

데이터 읽기 - int 값 읽기
package com.eomcs.io.ex04;

import java.io.FileInputStream;

public class Exam0120 {

  public static void main(String[] args) throws Exception {
    FileInputStream in = new FileInputStream("temp/test3.data");

    // Exam0110 실행하여 출력한 데이터를 read()로 읽는다.
    // read()는 1바이트를 읽어 int 값으로 만든 후 리턴한다.
    int value = in.read(); // 실제 리턴한 값은 0xD2이다.

    in.close();

    System.out.printf("%1$x(%1$d)\n", value);
  }
}

 

 

데이터 출력 - int 값 출력 II
package com.eomcs.io.ex04;

import java.io.FileOutputStream;

public class Exam0210 {

  public static void main(String[] args) throws Exception {
    FileOutputStream out = new FileOutputStream("temp/test3.data");

    int money = 1_3456_7890; // = 0x080557d2

    // int 메모리의 모든 바이트를 출력하려면,
    // 각 바이트를 맨 끝으로 이동한 후 write()로 출력한다.
    // 왜?
    // write()는 항상 변수의 마지막 1바이트만 출력하기 때문이다.
    out.write(money >> 24); // 00000008|0557d2
    out.write(money >> 16); // 00000805|57d2
    out.write(money >> 8);  // 00080557|d2
    out.write(money);       // 080557d2

    out.close();

    System.out.println("데이터 출력 완료!");

  }

}

 

 

데이터 읽기 - int 값 읽기 II
package com.eomcs.io.ex04;

import java.io.FileInputStream;

public class Exam0220 {

  public static void main(String[] args) throws Exception {
    FileInputStream in = new FileInputStream("temp/test3.data");

    // Exam02_1을 실행하여 출력한 데이터를 read()로 읽는다.
    // => 파일에서 4바이트를 읽어 4바이트 int 변수에 저장하라!
    // => 읽은 바이트를 비트이동 연산자를 값을 이동 시킨 후 변수에 저장해야 한다.
    // => 파일에 들어 있는 값 예: 080557d2
    int value = in.read() << 24;   // 00000008 =>   08000000
    value += (in.read() << 16);    // 00000005 => + 00050000
    value += (in.read() << 8);     // 00000057 => + 00005700
    value += in.read();            // 000000d2 => + 000000d2
    //==========================================>   080557d2

    in.close();

    System.out.printf("%08x(%1$d)\n", value);
  }
}

 

 

데이터 출력 - long 값 출력
package com.eomcs.io.ex04;

import java.io.FileOutputStream;

public class Exam0310 {

  public static void main(String[] args) throws Exception {
    FileOutputStream out = new FileOutputStream("temp/test3.data");

    // 우리나라 1년 예산
    long money = 400_0000_0000_0000L; // = 0x00016bcc41e90000

    // long 메모리의 모든 바이트를 출력하려면,
    // 각 바이트를 맨 끝으로 이동한 후 write()로 출력한다.
    // 왜? write()는 항상 변수의 마지막 1바이트만 출력하기 때문이다.
    out.write((int)(money >> 56)); // 00000000|00000000|016bcc41e90000
    out.write((int)(money >> 48)); // 00000000|00000001|6bcc41e90000
    out.write((int)(money >> 40)); // 00000000|0000016b|cc41e90000
    out.write((int)(money >> 32)); // 00000000|00016bcc|41e90000
    out.write((int)(money >> 24)); // 00000000|016bcc41|e90000
    out.write((int)(money >> 16)); // 00000001|6bcc41e9|0000
    out.write((int)(money >> 8));  // 0000016b|cc41e900|00
    out.write((int)money);         // 00016bcc|41e90000|

    out.close();

    System.out.println("데이터 출력 완료!");

  }

}

 

 

데이터 읽기 - long 값 읽기
package com.eomcs.io.ex04;

import java.io.FileInputStream;

public class Exam0320 {

  public static void main(String[] args) throws Exception {
    FileInputStream in = new FileInputStream("temp/test3.data");

    // Exam0310을 실행하여 출력한 데이터를 read()로 읽는다. 
    // => 파일에서 8바이트를 읽어 8바이트 long 변수에 저장하라!
    // => 읽은 바이트를 비트이동 연산자를 값을 이동 시킨 후 변수에 저장해야 한다.
    // => 파일에 들어 있는 값 예: 00016bcc41e90000
    long value = (long)in.read() << 56;   
    value += (long)in.read() << 48;
    value += (long)in.read() << 40;
    value += (long)in.read() << 32;
    value += (long)in.read() << 24;
    value += (long)in.read() << 16;
    value += (long)in.read() << 8;     
    value += in.read();            


    in.close();

    System.out.printf("%016x\n", value);
  }
}

 

 

데이터 출력 - String 출력
package com.eomcs.io.ex04;

import java.io.FileOutputStream;

public class Exam0410 {

  public static void main(String[] args) throws Exception {
    FileOutputStream out = new FileOutputStream("temp/test3.data");

    String str = "AB가각간";

    // str.getBytes(문자코드표)
    // => 문자열을 지정한 문자코드표에 따라 인코딩하여 바이트 배열을 만든다. 
    // => str.getBytes("UTF-8")
    //    UCS2 문자 ===> UTF-8 문자 
    out.write(str.getBytes("UTF-8"));

    out.close();

    System.out.println("데이터 출력 완료!");

  }

}

 

 

데이터 읽기 - String 값 읽기
package com.eomcs.io.ex04;

import java.io.FileInputStream;

public class Exam0420 {

  public static void main(String[] args) throws Exception {
    FileInputStream in = new FileInputStream("temp/test3.data");

    byte[] buf = new byte[100];

    int count = in.read(buf);

    // Exam0410의 실행 결과로 만들어진 파일을 읽어라!
    // 바이트 배열에 들어있는 값을 사용하여 String 인스턴스를 만든다.
    // new String(바이트배열, 시작번호, 개수, 문자코드표)
    // => 예) new String(buf, 0, 10, "UTF-8")
    //    buf 배열에서 0번부터 10개의 바이트를 꺼낸다.
    //    그 바이트는 UTF-8 코드로 되어 있다.
    //    이 UTF-8 코드 배열을 UCS2 문자 배열로 만들어 String 객체를 리턴한다.
    String str = new String(buf, 0, count, "UTF-8");

    in.close();

    System.out.printf("%s\n", str);
  }
}

 

 

FileOutputStream: float, double 값 출력
package com.eomcs.io.ex04;

import java.io.FileOutputStream;

public class Exam0510 {

  public static void main(String[] args) throws Exception {
    FileOutputStream out = new FileOutputStream("test6.data");

    float f = 12.375f; // hex: 41460000
    double d = 12.375; // hex: 4028c00000000000

    // f 출력
    out.write(Float.floatToIntBits(f) >> 24);
    out.write(Float.floatToIntBits(f) >> 16);
    out.write(Float.floatToIntBits(f) >> 8);
    out.write(Float.floatToIntBits(f));

    // d 출력
    out.write((int)(Double.doubleToLongBits(d) >> 56));
    out.write((int)(Double.doubleToLongBits(d) >> 48));
    out.write((int)(Double.doubleToLongBits(d) >> 40));
    out.write((int)(Double.doubleToLongBits(d) >> 32));
    out.write((int)(Double.doubleToLongBits(d) >> 24));
    out.write((int)(Double.doubleToLongBits(d) >> 16));
    out.write((int)(Double.doubleToLongBits(d) >> 8));
    out.write((int)(Double.doubleToLongBits(d)));

    out.close();

    System.out.println("실행 완료!");
  }

}

 

 

FileInputStream: float, double 값 읽기
package com.eomcs.io.ex04;

import java.io.FileInputStream;

public class Exam0520 {

  public static void main(String[] args) throws Exception {
    FileInputStream in = new FileInputStream("test6.data");

    // float 값에 해당하는 바이트 읽기
    int temp = (in.read() << 24) 
        + (in.read() << 16) 
        + (in.read() << 8) 
        + in.read();

    // int 변수에 저장된 것을 float 변수에 담기
    float f = Float.intBitsToFloat(temp);
    System.out.printf("%f\n", f);


    // double 값에 해당하는 바이트 읽기
    long temp2 = (((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();

    // long 변수에 저장된 것을 double 변수에 담기
    double d = Double.longBitsToDouble(temp2);
    System.out.printf("%f\n", d);

    in.close();

    System.out.println("실행 완료!");
  }

}

 

 

 

com.eomcs.io.ex05

 

 

객체 출력 - 인스턴스의 값을 출력
package com.eomcs.io.ex05;

import java.io.FileOutputStream;

public class Exam0110 {

  public static void main(String[] args) throws Exception {
    FileOutputStream out = new FileOutputStream("temp/test4.data");

    Member member = new Member();
    member.name = "AB가각간";
    member.age = 27;
    member.gender = true;

    // 인스턴스의 값을 출력하라!
    // 1) 이름 출력 
    byte[] bytes = member.name.getBytes("UTF-8");
    out.write(bytes.length); // 1 바이트
    out.write(bytes); // 문자열 바이트 

    // 2) 나이 출력 (4바이트)
    out.write(member.age >> 24);
    out.write(member.age >> 16);
    out.write(member.age >> 8);
    out.write(member.age);

    // 3) 성별 출력 (1바이트)
    if (member.gender) 
      out.write(1);
    else 
      out.write(0);

    out.close();

    System.out.println("데이터 출력 완료!");

  }

}
package com.eomcs.io.ex05;

public class Member {
  String name;
  int age;
  boolean gender; // true(여자), false(남자)

  @Override
  public String toString() {
    return "Member [name=" + name + ", age=" + age + ", gender=" + gender + "]";
  }
}

 

 

객체 읽기 - 파일이 데이터를 읽어 인스턴스로 만들기
package com.eomcs.io.ex05;

import java.io.FileInputStream;

public class Exam0120 {

  public static void main(String[] args) throws Exception {
    FileInputStream in = new FileInputStream("temp/test4.data");

    Member member = null;

    member = new Member();

    // 1) 이름 읽기
    int size = in.read(); // 이름이 저장된 바이트 배열의 수
    byte[] buf = new byte[size];
    in.read(buf); // 이름 배열 개수 만큼 바이트를 읽어 배열에 저장한다.
    member.name = new String(buf, "UTF-8");

    // 2) 나이(int) 읽기
    member.age = in.read() << 24;
    member.age += in.read() << 16;
    member.age += in.read() << 8;
    member.age += in.read();

    // 3) 성별 읽기
    if (in.read() == 1) 
      member.gender = true;
    else 
      member.gender = false;

    in.close();

    System.out.printf("%s\n", member);
  }
}

 

 

DataFileOutputStream을 이용하여 객체 출력 - 인스턴스의 값을 출력
package com.eomcs.io.ex05;

public class Exam0210 {

  public static void main(String[] args) throws Exception {
    DataFileOutputStream out = new DataFileOutputStream("temp/test4_2.data");

    Member member = new Member();
    member.name = "AB가각간";
    member.age = 27;
    member.gender = true;

    // 인스턴스의 값을 출력하라!
    // 1) 이름 출력 
    out.writeUTF(member.name); 

    // 2) 나이 출력 (4바이트)
    out.writeInt(member.age);

    // 3) 성별 출력 (1바이트)
    out.writeBoolean(member.gender);

    out.close();

    System.out.println("데이터 출력 완료!");

  }

}
package com.eomcs.io.ex05;

import java.io.FileOutputStream;

public class DataFileOutputStream extends FileOutputStream {

  public DataFileOutputStream(String filename) throws Exception {
    super(filename);
  }

  public void writeUTF(String str) throws Exception {
    // 상속 받은 write() 메서드를 사용하여 문자열 출력
    byte[] bytes = str.getBytes("UTF-8");
    this.write(bytes.length);
    this.write(bytes);
  }

  public void writeInt(int value) throws Exception {
    // 상속 받은 write() 메서드를 사용하여 int 값 출력
    this.write(value >> 24);
    this.write(value >> 16);
    this.write(value >> 8);
    this.write(value);
  }

  public void writeLong(long value) throws Exception {
    // 상속 받은 write() 메서드를 사용하여 long 값 출력
    this.write((int)(value >> 56));
    this.write((int)(value >> 48));
    this.write((int)(value >> 40));
    this.write((int)(value >> 32));
    this.write((int)(value >> 24));
    this.write((int)(value >> 16));
    this.write((int)(value >> 8));
    this.write((int)value);
  }

  public void writeBoolean(boolean value) throws Exception {
    // 상속 받은 write() 메서드를 사용하여 boolean 값 출력
    if (value) 
      this.write(1);
    else 
      this.write(0);
  }
}

 

 

DataFileInputStream으로 객체 읽기 - 파일이 데이터를 읽어 인스턴스로 만들기
package com.eomcs.io.ex05;

public class Exam0220 {

  public static void main(String[] args) throws Exception {
    DataFileInputStream in = new DataFileInputStream("temp/test4_2.data");

    Member member = null;

    member = new Member();

    // 1) 이름 읽기
    member.name = in.readUTF();

    // 2) 나이(int) 읽기
    member.age = in.readInt();

    // 3) 성별 읽기
    member.gender = in.readBoolean();

    in.close();

    System.out.printf("%s\n", member);
  }
}
package com.eomcs.io.ex05;

import java.io.FileInputStream;

public class DataFileInputStream extends FileInputStream {

  public DataFileInputStream(String filename) throws Exception {
    super(filename);
  }

  public String readUTF() throws Exception {
    // 상속 받은 read() 메서드를 사용하여 문자열 출력
    int size = this.read();
    byte[] bytes = new byte[size];
    this.read(bytes); // 이름 배열 개수 만큼 바이트를 읽어 배열에 저장한다.
    return new String(bytes, "UTF-8");
  }

  public int readInt() throws Exception {
    // 상속 받은 read() 메서드를 사용하여 int 값 출력
    int value = 0;

    value = this.read() << 24;
    value += this.read() << 16;
    value += this.read() << 8;
    value += this.read();
    return value;
  }

  public long readLong() throws Exception {
    // 상속 받은 read() 메서드를 사용하여 long 값 출력
    long value = 0;
    value += (long) this.read() << 56;
    value += (long) this.read() << 48;
    value += (long) this.read() << 40;
    value += (long) this.read() << 32;
    value += (long) this.read() << 24;
    value += (long) this.read() << 16;
    value += (long) this.read() << 8;
    value += this.read();
    return value;
  }

  public boolean readBoolean() throws Exception {
    // 상속 받은 read() 메서드를 사용하여 boolean 값 출력
    if (this.read() == 1)
      return true;
    else
      return false;
  }
}