26. File & In/OutStream

sumin·2023년 8월 5일
0

아카데미

목록 보기
26/82
post-thumbnail

File 생성 및 삭제

java.io.File 클래스

  1. 파일, 디렉터리(폴더)를 관리하는 클래스이다.
  2. 파일, 디렉터리를 생성/삭제가 가능하다.
  3. 파일, 디렉터리의 각종 정보(이름, 크기, 최종 수정일 등)를 확인할 수 있다.

경로 작성 방법

  1. 윈도우 : 백슬래시() ,Java에서 백슬래시 입력하는 방법 \
  2. 리눅스 : 슬래시(/)
  3. java.io.File 클래스에는 플랫폼에 따라서 경로 구분자를 자동으로 바꿔주는 separator 필드 값이 있다.
// 파일의 생성/삭제
// 디렉터리를 file 객체로 생성
      File dir = new File("C:/storage"); 
      //윈도우 플랫폼에서도 슬래시(/)가 인식된다. 
      
      //디렉터리가 없으면 만들기 
      if(!dir.exists()) {
        dir.mkdirs();
      }
      
      //파일을 file객체로 생성
      File file = new File(dir, "myfile.txt");
  try {
      //파일이 있으면 지우고 없으면 만들기
      if(file.exists()) {
        file.delete();
        System.out.println("myfile.txt 파일 삭제 완료 ");
      }else {
        file.createNewFile(); //반드시 예외처리를 해야하는 코드 (checked Exception 인 IOException
        System.out.println("myfile.txt 파일 생성 완료");
    }
    }catch (IOException e) {
      e.printStackTrace();
    }
  }

파일, 디렉터리 정보 확인

listFile() : 모든 File 객체를 저장한 File[]반환
getName() : 이름 반환
getParent() : 저장된 디렉터리 반환
getPath() : getParent() + getName()
lastModified() : 최종 수정일을 long타입으로 반환
lenght() : 크기를 long 타입의 바이트 단위로 반환
isDirectory() : 디렉터리면 true 반환
isFile() : 파일이면 true 반환

Stream

Stream 이란

스트림(Stream)은 자바 8 API에 새로 추가된 기능이다. 스트림을 이용하면 선언형(더 간결하고 가독성이 좋도록)으로 컬렉션 데이터를 처리할 수 있다.
스트림(Stream)은 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소로 정의할 수 있다.

쉽게 말해 스트림은 데이터를 받고 출력하는 작업을 도와주는 중간역활을 하며, 문자단위로 처리하느냐 , 바이트단위로 처리하느랴에 따라 종류가 나뉜다.

보통 문자 단위이면 Reader 바이트 단위이면 Stream 이다.

OutputStream

FileOutputStream

java.io.OutputStream 클래스

1. FileOutputStream : byte 단위로 파일을 기록하는 클래스, 끝나고 반드시 close()해주어야한다.
2. 바이트 기반의 출력 스트림이다.
3. 출력단위
  1) int
  2) byte[]

 //디렉터리를 File 객체로 만들기
    File dir = new File("C:/storage");
    if(!dir.exists()) {
      dir.mkdirs();
    }
    
    // 파일을 File 객체로 만들기 
    File file = new File(dir, "ex01.dat");
    
    // 파일 출력스트림 선언
    FileOutputStream fout = null;   //선언만
    try {
      
      // 파일 출력스트림 생성(반드시 예외 처리가 필요한 코드 )
      // 1.생성모드 : 언제나 새로 만든다.(덮어쓰기)               new FileOutPutstream(file)
      // 2.추가모드 : 새로 만들거나 기존 파일에 추가한다.         new FileOutPutstream(file, true)      
      fout = new FileOutputStream(file); // 생성
      
      // 출력할 데이터(파일로 보낼 데이터)
      int c = 'A';    // int
      String s = "pple";
      byte[] b = s.getBytes(); // byte[] : String을 byte[]로 변환
      
      // 출력(파일로 데이터 보내기)
      fout.write(c);
      fout.write(b);
      System.out.println(file.getPath() + " 파일 크기 : " + file.length() + "바이트");
      
    }catch(IOException e ) {
      e.printStackTrace();
    } finally {//항상 마지막에 수행되는 곳
      try{
        if(fout != null) {   
          fout.close();  //exception을 요구하기에(예외처리가 필요하기 떄문에) 트라이  다시 써줌 
        }                //출력 스트림은 반드시 닫아줘야함  안하면 파일이 안만들어진다.        
      }catch (IOException e) {
        e.printStackTrace();        
      }
    }

bufferedOutputStream

  1. 바이트 단위로 출력한다.
  2. 내부 버퍼를 가지고 있는 출력스트임이다.
  3. 많은 데이터를 한 번에 출력하기 때문에 속도 향상을 위해서 사용한다.
  4. 보조스트림이므로 메인스트림과 함께 사용한다.
    *자바는 이미 파일이 있으면 덮어 쓰기를 한다.
File dir = new File("C:/storage");
    if(!dir.exists()) {
      dir.mkdir();
    }
    
    File file = new File(dir, "ex03.dat");
    
    //버퍼출력스트림 선언 출력속도가 빠름
    BufferedOutputStream bout =null; 
    
    try {
      bout = new BufferedOutputStream(new FileOutputStream(file));
      
      String one = "안녕하세요";
      int two = '\n';
      String three = "반갑습니다.";
   
      
      bout.write(one.getBytes("UTF-8"));
      bout.write(two);
      bout.write(three.getBytes(StandardCharsets.UTF_8)); //getBytes("UTF-8")과 동일하다. 
    
      System.out.println(file.getPath() + " 파일 크기 : " + file.length() + "바이트");    
    }catch(IOException e) {
      e.printStackTrace();
    }finally {
      try {
        if(bout != null) {
          bout.close();
        }
      }catch (IOException e) {
          e.printStackTrace();
        }
      }

DataOutputStream

  1. int. double. String 등의 변수를 그대로 출력하는 출력스트림이다.
  2. 보조스트림이므로 메인스트림과 함께 사용한다.
 File dir = new File("C:/storage");
    if(!dir.exists()) {
      dir.mkdir();
    }
    
    File file = new File(dir, "ex04.dat");
    // 데이터출력스트림 선언
    DataOutputStream dout =null; 
    
    
    try {
      //데이터출력스트림 생성(반드시 예외 처리가 필요한 코드 )
      dout = new DataOutputStream(new FileOutputStream(file));
      
      String name = "tom";
      int age = 50;
      double height = 180.5;
      String school = "가산대학교";
      
      //출력(파일로 내보내기)
      dout.writeChars(name);
      dout.writeInt(age);
      dout.writeDouble(height);
      dout.writeUTF(school);
      
      System.out.println(file.getPath() + " 파일 크기 : " + file.length() + "바이트");    
    }catch(IOException e) {
      e.printStackTrace();
    }finally {
      try {
        if(dout != null) {
          dout.close();
        }
      }catch (IOException e) {
          e.printStackTrace();
        }
      }

java.io.ObjectOutputStream 클래스

  1. 객체를 그대로 출력하는 출력스트림이다.
  2. 직렬화(Serializable)된 객체를 보낼 수 있다.

    직렬화란
     자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술과 바이트로 변환된 데이터를 다시 객체로 변환하는 기술(역직렬화)을 아울러서 이야기한다.
     시스템적으로 이야기하자면 JVM(Java Virtual Machine 이하 JVM)의 메모리에 상주(힙 또는 스택)되어 있는 객체 데이터를 바이트 형태로 변환하는 기술과 직렬화된 바이트 형태의 데이터를 객체로 변환해서 JVM으로 상주시키는 형태를 같이 이야기한다.

  3. 보조스트림이므로 메인스트림과 함께 사용한다.
File dir = new File("C:/storage");
      if(!dir.exists()) {
        dir.mkdir();
      }
      
      File file = new File(dir, "ex05.dat");
      
      //객체출력스트림 선언 출력속도가 빠름
      ObjectOutputStream oout =null; 
      
      
      try {
        //객체출력스트림 생성(반드시 예외 처리가 필요한 코드 )
        oout = new ObjectOutputStream(new FileOutputStream(file));
        
        String name = "tom";
        int age = 50;
        double height = 180.5;
        String school = "가산대학교";
        Student student =new Student(name, age, height, school);
        
        //출력(파일로 내보내기)
       oout.writeObject(student);
       
       System.out.println(file.getPath() + " 파일 크기 : " + file.length() + "바이트");    
        
      }catch(IOException e) {
        e.printStackTrace();
      }finally {
        try {
          if(oout != null) {
            oout.close();
          }
        }catch (IOException e) {
            e.printStackTrace();
          }
        }

Student

public class Student implements Serializable{

  /**
   * 
   */
  private static final long serialVersionUID = -988261495718805568L;
  private String name;
  private int age;
  private double height;
  private String school;
  
  public Student() {
    
  }

  public Student(String name, int age, double height, String school) {
    super();
    this.name = name;
    this.age = age;
    this.height = height;
    this.school = school;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public double getHeight() {
    return height;
  }

  public void setHeight(double height) {
    this.height = height;
  }

  public String getSchool() {
    return school;
  }

  public void setSchool(String school) {
    this.school = school;
  }

  @Override
  public String toString() {
    return "Student [name=" + name + ", age=" + age + ", height=" + height + ", school=" + school + "]";
  }
}

InputStream

java.io.InputStream 클래스

  1. 바이트 기반의 입력스트림이다.
  2. 입력단위 1) int 2) byte[]
// 디렉터리를 File 객체로 만들기
    File dir = new File("C:/storage");

    // 파일을 File 객체로 만들기
    File file = new File(dir, "ex01.dat");

    // 파일입력스트림 선언
    FileInputStream fin = null;

    try {

      // 파일입력스트림 생성(반드시 예외처리 필요, 파일이 없으면 예외 발생)
      fin = new FileInputStream(file);

      // 입력할 데이터 저장 변수
      int c = 0;

      // 1개씩 읽은 데이터를 누적할 StringBuilder 생성
      StringBuilder sb = new StringBuilder();

      // read() 메소드
      // 1. 1개 데이터를 읽어서 반환한다.
      // 2. 읽은 내용이 없으면 -1을 반환한다.

      // 반복문 : 읽은 내용이 -1 이 아니면 계속 읽는다.
      while ((c = fin.read()) != -1) {
        sb.append((char) c);
      }
      // 결과확인
      System.out.println(sb.toString());

    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        if (fin != null) {
          fin.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

java.io.BufferedInputStream 클래스

  1. 내부 버퍼를 가지고 있는 입력스트림이다.
  2. 많은 데이터를 한번에 입력받기 때문에 속도 향상을 위해서 사용한다.
  3. 보조스트림이므로 메인스트림과 함께 사용한다.
 File dir = new File("C:/storage");

    File file = new File(dir, "ex03.dat");
    // 버퍼입력스트림 선언
    BufferedInputStream bin = null;

    try {

      // 버퍼입력스트림 생성(반드시 예외처리 필요, 파일이 없으면 예외 발생)
      bin = new BufferedInputStream(new FileInputStream(file));

      // 입력할 데이터 저장 변수
      byte[] b = new byte[4]; // 임의로 크기 설정(최대 4바이트 입력 가능(컴퓨터 성능이 안좋을때) 컴퓨터 성능이 좋다면 더 큰수도 가능

      // 실제로 읽은 바이트 수 저장 변수
      int readByte = 0;

      // 1개씩 읽은 데이터를 누적할 StringBuilder 생성
      StringBuilder sb = new StringBuilder();

      // read(byte[] b) 메소드
      // 1. 파라미터로 전달된 byte[] b 에 읽은 내용을 저장한다.
      // 2. 실제로 읽은 바이트 수를 반환한다.
      // 3. 읽은 내용이 없으면 -1을 반환한다.

      // 반복문 : read()의 반환값이 -1 이 아니면 계속 읽는다.
      while ((readByte = bin.read(b)) != -1) {
        sb.append(new String(b, 0, readByte)); // 배열 b의 인덱스 0부터 readByte 개 데이터를 String으로 변환한다.
      }

      /*
       * 15바이트 "abcdefghijklmno"를 4바이트씩 읽는 방식
       * 
       * byte[] b readByte new String(b, 0, readByte)
       * 
       * 1차 Loop ┌---------------┐ 
       *          │ a | b | c | d │ 4 배열 b의 인덱스 0부터 4개 데이터를 String으로변환한다. 
       *          └---------------┘ 
       * 2차 Loop ┌---------------┐ 
       *          │ e | f | g | h │  4 배열 b의 인덱스 0부터 4개 데이터를 String으로 변환한다. 
       *          └---------------┘ 
       * 3차 Loop ┌---------------┐ 
       *          │ i | j | k | l │ 4 배열 b의 인덱스 0부터 4개 데이터를 String으로 변환한다. 
       *          └---------------┘ 
       * 4차 Loop ┌---------------┐ 
       *          │ m | n | o | l │ 3 배열 b의 인덱스 0부터 3개 데이터를 String으로 변환한다. 
       *          └---------------┘ 
       *                         ↑ 
       *                         └---- 이전 Loop에서 읽은 데이터이므로 사용하면 안 된다.
       */
      // 결과확인
      System.out.println(sb.toString());

    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        if (bin != null) {
          bin.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

java.io.DataInputStream 클래스

  1. int, double, String 등의 변수를 그대로 입력받는 입력스트림이다.
  2. 보조스트림이므로 메인스트림과 함께 사용한다.

DataOutputStream과 DataInputStream을 사용하면
바이트 기반 입출력에서도 한글 처리가 가능하다. (writeUTF, readUTF 메소드 이용)

File dir = new File("C:/storage");

    File file = new File(dir, "ex04.dat");

    // 데이터입력스트림 선언
    DataInputStream din = null;

    try {

      // 데이타입력스트림 생성(반드시 예외처리 필요, 파일이 없으면 예외 발생)
      din = new DataInputStream(new FileInputStream(file));

      // 순서대로 입력받기
      char ch1 = din.readChar(); // 't'
      char ch2 = din.readChar(); // '0'
      char ch3 = din.readChar(); // 'm'
      int age = din.readInt(); // 50
      double height = din.readDouble(); // 180.5
      String school = din.readUTF(); // 가산대학교

      // 결과확인
      System.out.println("" + ch1 + ch2 + ch3);
      System.out.println(age);
      System.out.println(height);
      System.out.println(school);

    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        if (din != null) {
          din.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

java.io.ObjectInputStream 클래스

  1. 객체를 그대로 입력받는 입력스트림이다.
  2. 직렬화(Serializeable)된 객체를 입력 받을 수 있다.
  3. 보조스트림이므로 메인스트림과 함께 사용한다.

    File file = new File(dir, "ex05.dat");

    // 데이터입력스트림 선언
    ObjectInputStream oin = null;

    try {

      // 데이타입력스트림 생성(반드시 예외처리 필요, 파일이 없으면 예외 발생)
      oin = new ObjectInputStream(new FileInputStream(file));

      // 객체 순서대로 입력받기
      Student s = (Student) oin.readObject();

      // 결과확인

      System.out.println(s);

    } catch (IOException | ClassNotFoundException e) {
      e.printStackTrace();
    } finally {
      try {
        if (oin != null) {
          oin.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
profile
백엔드 준비생의 막 블로그

0개의 댓글