• Home
  • About
    • Young's Github Pages photo

      一日不作一日不食

    • About
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

Java 정리 28

20 Dec 2018

Reading time ~5 minutes

Java 정리 28 - IO Stream(2)


한글 포함한 파일 입력받기

  • 한글 처리를 하기 위해 8bit Stream과 16bit Stream을 연결하여 파일 데이터를 읽어들여야 한다.
File f = new File("c:/.../temp/java_read.txt");
FileInputStream fis = new FileInputStream(f);       // 파일과 연결
InputStreamReader isr = new InputStreamReader(fis); // 8bit-16bit 연결
BufferedReader fb = new BufferedReader(isr);        // 속도개선, 줄단위 읽기

String temp = "";
while ((temp = br.readLine()) != null) { 
    ... // 한줄을 읽어들인 temp를 사용
}

01

// 한글 입력된 파일을 입력받기
public class UseFileInputStream {
     
     public UseFileInputStream() {
           File file = new  File("C:/.../temp/java_read.txt");
           
           if (file.exists()) {
                
                try {
                     // 스트림을 생성하여 JVM에서 HDD의 파일과  연결
                     // 한글처리를 위해 16bit Stream과 연결
                     BufferedReader br = new BufferedReader(
                                new InputStreamReader(new  FileInputStream(file)));
                     
                     String temp = "";
                     
                     while((temp = br.readLine()) != null) {
                           System.out.println(temp);
                     }
                     
                     br.close();
                } catch (FileNotFoundException fnfe) {
                     fnfe.printStackTrace();
                } catch (IOException ie) {
                     ie.printStackTrace();
                }
           } else {
                System.out.println("경로나 파일명을  확인하세요.");
           }
     }
     public static void main(String[] args) {
           new UseFileInputStream();
     }
}

02

  • 위 코드의 문제는 연결 후 내용 처리하다가 예외 터지면 Stream close가 수행이 안될 수 있음!
    • finally에 close를 구현
    • try~catch가 중복구현되면 소스가 복잡해짐
      • throws로 던져버리고 호출한 곳에서 try~catch로 예외처리
      • 이렇게 많이 구현하기 때문에 try~finally를 많이 사용
public class UseFileInputStream {
     public UseFileInputStream() throws IOException {
           File file = new  File("C:/.../temp/java_read.txt");
           if (file.exists()) {
                BufferedReader br = null;
                try {

//                   FileInputStream fis = new  FileInputStream(file);
//                   InputStreamReader isr = new  InputStreamReader(fis);
//                   br = new BufferedReader(isr);

                     br = new BufferedReader(new  InputStreamReader(new FileInputStream(file)));

                     String temp = "";
                     
                     while ((temp = br.readLine()) != null) {
                           System.out.println(temp); 
                     }
                } finally {
                     if (br != null) br.close(); // 객체가 존재한다면(연결돼있다면)
                }
           } else {
                System.out.println("경로나 파일명을  확인하세요.");
           }
     }
     public static void main(String[] args) {
           try {
                new UseFileInputStream();
           } catch (IOException e) {
                e.printStackTrace();
           }
     }
}

FileReader

  • 원천데이터가 한글을 포함한 데이터라면 16bit Stream을 바로 사용

03

File f = new File("경로");

FileReader fr = new FileReader(f);          // File 객체로 바로 16bit Stream 생성
BufferedReader br = new BufferedReader(fr); // 한줄 읽기 위해 fr과 br 연결

04

// 한줄로
BufferedReader br = new BufferedReader(new FileReader(f));
// 16bit Stream만 사용하여 파일읽기
public class UseFileReader {
     public void useFileReader() throws IOException {
          BufferedReader br = null;
          
          try {
              File f = new  File("C:/.../temp/java_read.txt");
              // 1. 근원지 파일에 스트림 연결
              FileReader fr = new FileReader(f);
              // 2. 줄단위 읽어들이는 기능을 가진 스트림 연결
              br = new BufferedReader(fr);
              
              String temp = "";
              // 한줄씩 읽어들여 읽어들인 내용이 존재한다면
              while ((temp = br.readLine()) != null) {
                   System.out.println(temp); // 출력
              }
              
          } finally {
              // 연결된 스트림을 끊는다.
              if (br != null) br.close();
          }
     }

     public static void main(String[] args) {

          UseFileReader ufr = new UseFileReader();

          try {
              ufr.useFileReader();
          } catch (IOException e) {
              e.printStackTrace();
          }
     }
}

출력 스트림

05


File 출력

  • 8bit Stream
    • FileOutputStream
      • 입력된 경로의 파일을 생성
      • 없으면 생성하고 파일이 존재하면 덮어쓴다.

06

// 1. File 생성
File file = new File("C:/.../temp/java_write.txt");

// 2. Stream 생성
FileOutputStream fos = new FileOutputStream(file);

// 3. 스트림의 데이터를 쓴다.
// write메소드는 스트림상에 데이터를 씀
fos.write(정수|byte[]);

// 4. 스트림에 기록된 데이터를 분출
// flush를 사용해야 데이터가 스트림 밖으로 분출된다.
fos.flush();

// 5. 스트림을 다 사용한 후엔 닫는다.
fos.close();
// JVM에서 발생한 데이터가 정수, byte[]인 경우에 File로  저장하는 FileOutputStream사용
public class UseFileOutputStream {
     public void useFileOutputStream() throws IOException  {
          int i = 65;
          // 1. File class 생성
          File file = new  File("C:/.../temp/java_write.txt");
          // 2. FileOutputStream 생성 -> 입력된 경로에  파일이 생성된다.
          // 파일이 없다면 생성하고, 파일이 있다면 덮어  쓴다.
          FileOutputStream fos = null;
          try {
              boolean flag = false;
              if (file.exists()) {
                   boolean[] temp = { false, true, true  };
                   int select =  JOptionPane.showConfirmDialog(null,  "덮어쓰시겠습니까?");
                   flag = temp[select];
              }
              if (!flag) {
                   fos = new FileOutputStream(file);
                   fos.write(i); // 값을 스트림에 기록  (수에 대한 문자가 출력됨)
                   fos.flush();
                   System.out.println("파일 기록 완료");
              }
          } finally {
              // 스트림에 기록된 내용이 있다면 분출하고  연결을 끊어야 함
              if (fos != null) {
                   fos.close();
              }
          }
     }
     public static void main(String[] args) {
          UseFileOutputStream ufos = new  UseFileOutputStream();
          try {
              ufos.useFileOutputStream();
          } catch (IOException e) {
              e.printStackTrace();
          }
     }
}

문자열 쓰기

  • 8bit Stream과 16bit Stream을 사용하면 문자열을 File에 기록가능
    • 16bit OutputStream들은 Writer를 상속받는 클래스들
    • OutputStreamWriter를 사용하면 문자열을 파일로 쓸 수 있다.
      • 속도개선을 위해 BufferedWriter를 사용

07

String d = "안녕!";

// 1. File생성
File file = new File("C:/.../temp/java_write2.txt");

/*// 2. Stream 생성
// 파일을 생성하는 FileOutputStream : 폴더가 없으면 FileNotFoundException 발생
FileOutputStream fos = new FileOutputStream(file);

// 문자열을 쓰기 위한 OutputStreamWriter : 속도가 느림
OutputStreamWriter osw = new OutputStreamWriter(fos);

// 느린 속도를 개선하기 위한 BufferedWriterStream 연결 
BufferedWriter bw = new BufferedWriter(osw);
*/

// 위 과정을 한줄로 줄일 수 있다.
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
        new FileOutputStream(file)));

// 3. Stream 기록
bw.write(d);

// 4. Stream에 기록된 내용을 목적지로 분출(flush)
bw.flush();

// 5. Stream 끊기
bw.close();
/**
* 8bit Stream과 16bit Stream을 연결 사용하여 문자열 데이터를
* File에 기록
*/
public class UseFileOutputStream2 {
     public UseFileOutputStream2() throws IOException {
          String data = "오지고요 지리고요 고요고요  고요한 밤이고요";
          
          // 1. File 객체 생성 : 파일이 존재한다면 덮어 쓸 것인지를 판단하기 위해 만듦.
          File file = new  File("C:/.../temp/java_write2.txt");
          
          boolean flag = false; // 파일이 없을 때
          if (file.exists()) {
              boolean[] flagVal = { false, true, true };  // 예, 아니오, 취소
              flag =  flagVal[JOptionPane.showConfirmDialog(null, "덮어 쓰시겠습니까?")];
          }
          
          // 2. 스트림 생성
          if (!flag) {
              BufferedWriter bw = null;
              
              try {
                   /*// 파일을 생성하는 Stream : FileNotFoundException이 발생(폴더가 없을 때)
                   FileOutputStream fos = new  FileOutputStream(file);
                   // 문자열을 쓰기 위한 Stream 연결 :  (속도가 느리다)
                   OutputStreamWriter osw = new  OutputStreamWriter(fos);
                   // 느린 속도를 개선하기 위한 Stream  연결 :
                   bw = new BufferedWriter(osw);*/
                   
                   bw = new BufferedWriter(new  OutputStreamWriter(
                             new  FileOutputStream(file)));
                   
                   bw.write(data); // 스트림에 데이터를 기록
                   bw.flush();     // 목적지에 파일로 분출
                   
                   System.out.println("파일에 기록  완료!");
              } finally {
                   
                   // 스트림 객체가 생성되어 있다면  연결을 끊음
                   if(bw!=null) { bw.close(); }
              }
          }
     }
     
     public static void main(String[] args) {
          try {
              new UseFileOutputStream2();
          } catch (IOException e) {
              e.printStackTrace();
          }
     }
}

FileWriter

  • 16bit Stream을 바로 사용하기
  • FileWriter 사용
// 16bit Stream만 사용
BufferedWriter bw = null;
              
try {
    bw = new BufferedWriter(new  FileWriter(file));

메모장 Open, Save, font서식 저장 기능 구현

  • 파일 입력 Stream을 활용하여 기존에 구현했던 메모장 Open 기능 구현
    • BufferedReader 사용
  • 파일 출력 Stream을 활용하여 메모장 Save 기능 구현
    • BufferedWriter 사용
  • 마지막 적용했던 서식을 저장하는 fontConfig.dat를 생성, 재실행시 읽어들여 기본설정으로 적용
    • BufferedReader, BufferedWriter 사용
  • JavaMemo 패키지

숙제

  • 메모장앱 종료시 저장여부 묻고 종료되도록 구현
    • '닫기' 메뉴아이템, 윈도우 닫기 버튼클릭 시 closeMemo() 메소드 호출되도록 구현
public void closeMemo() {
     boolean flag = false;
     if  (!taNoteData.equals(jm.getTaNote().getText())) {
          
          int select =  JOptionPane.showConfirmDialog(jm,
                    "변경사항이 있습니다. 저장하고  종료하시겠습니까?");
          switch(select) {
          case JOptionPane.OK_OPTION :
               saveMemo();
               break;
          case JOptionPane.NO_OPTION :
               break;
          case JOptionPane.CANCEL_OPTION :
               flag = true;
          }
     }
     
     if(!flag) {
          jm.dispose();
     }
}


Java