[F-lab 모각코 챌린지 36일차] TIL

JeongheeKim·2023년 7월 6일

TIL

목록 보기
36/66

학습계획


  • I/O
  • Stream
  • Reader/Writer

Today I Learned


  • File 클래스
    • local 파일/디렉토리를 추상화한 클래스
    • 파일/디렉토리 정보를 얻는 것, 생성, 삭제만 가능
    • 파일에 정보를 쓰거나 읽을 수 는 없다. → 파일 입출력 스트림으로만 가능

I/O

  • input, output을 통칭한다. 자바에서는 JVM기준으로 파일을 읽거나, 파일을 쓰고 외부로 전송하는것을 뜻한다.
  • jdk1.0에서 java.io패키지에 소개되었다.
  • 동기방식 지원
    • I/O관련 API의 작업이 종료되어야 다음 작업 수행 가능
  • blocking 방식 지원
    • 어떤 작업이 완료 될때까지 대기하고있는것(대기상태)
    • thread를 종료하는 방식인 interrupt를 사용해서 블로킹 상태를 빠져나갈 수 없다. 스트림을 닫는방법만이 블로킹을 빠져나갈 수 있다.
  • 적절한 사용 예시
    • 연결 클라이언트 수가 적을때
    • 전송되는 데이터가 대용량일때
      • buffer를 사용할 경우 무한정 큰 데이터를 담을 수 없기때문
    • 순차적으로 처리될 필요가 있을 경우

Stream 사용

스트림이란?

  • 여러가지 형식의 데이터 입출력의 추상화 개념
  • 데이터의 흐름이 단방향 : 입력스트림, 출력 스트림이 따로 존재
  • 데이터의 흐름이 끊기지 않고 연속적인것
  • 자바에서 사용되는 스트림은 크게 byte stream, char stream으로 나뉜다.

InputStream / OutputStream

  • 바이트 기반의 데이터를 읽고 쓰는 기능
  • 단, 스트림으로 읽고 쓰는것은 데이터를 별도 저장하지 않으면, 입력 데이터의 위치를 이동해가며 자유롭게 이용이 불가
  • InputStream / OutputStream 이라는 추상클래스를 통해 제공된다.
  • 읽기/쓰기 대상에 따라 추상메서드를 구현한 구현체가 생성되었다.
  • 자바에서 사용 되는 대부분의 데이터 타입은 객체로 표현되어지다보니 Object Input/OutputStream 도 생성되었다.
  • java.io 패키지에 있는 클래스를 사용할때는 리소스(파일 or 네트워크 스트림을 통한 작업이 가능한것들)를 닫기 위해 Closeable 인터페이스의 close()를 호출해야한다.
  • OutputStream의 flush()는 바이트 단위마다 쓰고 저장하는것이 아닌 버퍼 공간에 쌓았다가 flush()가 호출되면 대기하고 있는 데이터를 강제로 쓰게하는 기능이다.

Reader / Writer

  • char 기반의 문자열 로만 되어있는 파일을 읽고 쓰는 기능
  • 다른 클래스와 다르게 Appendable 인터페이스를 구현받았다. 이는 각종 문자열 추가를 위해 선언되었다. 이 인터페이스를 구현한 클래스로는 대표적으로 String, StringBuffer, StringBuilder가 있다.
  • IO방식에서는 1바이트씩 데이터를 읽고 쓰기 때문에 NIO에 비해 느림
  • Writer 클래스에있는 wirte(), append()메서드를 사용하여 데이터를 쓰면 메소드를 호출 했을때마다 파일에 쓰기때문에 비효율적임. BufferedWirte 라는 클래스를 제공하여 버퍼공간을 사용하여 데이터를 쓸수있도록 제공한다. buffer의 공간이 차게되면 데이터를 저장도록 도와준다.
  • FileWriter 객체 생성 시 IOException이 발생할 수 있는 경우
    1. 매개 변수로 넘어온 파일 이름이 아닌 경로인 경우
    2. 해당 파일이 존재하지 않지만, 권한 등의 문제로 생성할 수 없는 경우
    3. 파일이 존재하지만, 여러이유로 파일을 열 수 없는 경우
  • FileWriter, BufferedWriter를 try문 안에서 선언하면, finally문에서 close()를 호출할 수 없다.
  • 리소스 관련 객체를 닫을때는 마지막으로 open한 객체부터 닫아야한다.
public class FileTest {
    public void readFile(String fileName)  {
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
        try {
            **fileReader = new FileReader(fileName);
            bufferedReader = new BufferedReader(fileReader);
            String data;
            while((data = bufferedReader.readLine()) != null) {
                System.out.println(data);
            }**
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Scanner클래스는 텍스트 기반의 기본 자료형이나 문자열 데이터를 처리하기 위한 클래스이다.

정규표현식을 사용하여 데이터를 잘라서 쓸수도 있다. 위의 코드에서 Scanner로 리팩토링 했는데 코드의 양이 줄어든것도 확인 할 수 있다.

public void readFile(String fileName) {
        File file = new File(fileName);
        Scanner scanner = null;
        try {
            scanner = new Scanner(file);
            while (scanner.hasNextLine()) {
                System.out.println(scanner.nextLine());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (scanner != null) {
                scanner.close();
            }
        }
    }

0개의 댓글