TIL / JAVA 4주차(3) / NIO

병아리코더 아카이브·2023년 9월 9일

JAVA

목록 보기
14/20
post-thumbnail

NIO ( New Input/Output )

  • NIO 는 기존의 IO 에 Asynchronous 와 Channel 이라는 개념을 추가하였다. ( JDK 1.8 버전부터 )

Path / FileSystem / Files

  • IO 에서는 파일의 경로, 정보 등의 각종 처리들을 File 객체를 통해 수행하였다.
    NIO 는 File 객체에서 한번에 사용했던 기능들을 각각 다른 클래스로 전문화하였다.

Channel

  • IO 에서는 파일을 읽고 쓰기 위해 Stream 을 생성해야 한다.

  • 또한 기존 IO 는 속도가 느리다는 단점이 있다. 또한 쓰레드가 블로킹되어 다중 접근이 불가능하다.

NIO 에서는 Channel 을 이용하면 양방향으로 입출력이 가능하다.

  • Channel 은 비동기적으로 데이터를 읽거나 쓸 수 있고, 입출력 수행시 Blocking / Non-blocking 특징을 모두 지원한다.
  • 채널은 항상 Buffer 라는 NIO 컴포넌트와 함께 사용된다.
    그래서 채널에서 데이터를 버퍼로 읽어거나 버퍼에 있는 데이터를 채널로 쓴다.

Buffer

  • 채널에서 데이터를 전송하거나 읽어오기 위해서는 Buffer 라는 컴포넌트를 이용해야 한다. 채널 객채에서 제공하는 read( ) write( ) 메서드는 항상 버퍼를 사용한다.

  • Buffered 보조 스트림과 역할은 동일하게 한꺼번에 가져와 버퍼에 저장하고 한꺼번에 전송한다.

응용01 - Path 와 Files 메서드 이용

  • 기존에는 File 객체를 생성하고 exist( ) 와 mkdir( ) 메서드로 File 경로의 폴더가 존재하는지 여부와 폴더 생성이 가능하였다.
  • NIO 에서는 우선 import java.nio.file.* 를 가지고 오면 Paths 와 Files 클래스를 다룰 수 있게 된다.
  • Paths.get(경로) 를 통해 파일의 경로를 Path 타입의 변수에 저장한다.
  • 이를 Files.notExists( Path path ) 로 받아 경로에 폴더가 존재하지 않으면 true 를 반환한다.
  • 또 Files.createDirectories( Path path ) 로 폴더 생성이 가능하다.

여기서 Paths 와 Files 객체 생성 없는 것은 사용하는 메서드들이 static 메서드이기 때문이다.

  • 기존에는 File 객체의 createNewFile( ) 메서드를 사용하여 파일을 생성하였다.

  • NIO 에서는 Files.createFiles( Path path ) 로 파일을 생성한다.

  • 생성된 파일리스트를 하나하나 보여주기 위해 기존에는 File 객체의 listFiles( ) 를 이용하여 파일리스트 배열을 생성하였다.
  • 그리고 생성한 배열을 향상된 for문을 이용하여 하나씩 꺼내
    isDirectory( ) : 디렉토리 여부
    getName( ) : 파일 or 디렉토리 이름
    length( ) : 크기(byte)
    isHidden( ) : 숨김파일 여부
    를 확인하고 이 값을 HashMap 에 하나하나 넣은 후 가변적인 공간인 ArrayList 에 HashMap 을 하나씩 담았다.
  • NIO 에서는 HashMap 에 파일의 정보를 넣고 이를 ArrayList 에 담는 것은 동일하다.
  • 하지만 Files.list( Path path ) 를 넣어 파일의 리스트를 생성하고 이를 Stream<Path> 타입의 변수에 넣는다.
  • 이 Stream 의 내용을 읽기 위해서 Iterator 을 통해서 Iterator 타입으로 변환한다.
  • 그리고 hasNext( ) 를 통해 다음 요소의 존재를 확인하고 next( ) 를 통해 현재 요소를 Path 타입의 변수 info 저장하고 다음 요소로 이동한다.
  • 저장한 Path 와 Files 클래스의 메서드를 사용하여 아까와 같이 파일의 정보를 얻는다.
    Files.isDirectory( Path path ) : 디렉토리 여부
    getFileName( ) : 파일 or 디렉토리 이름 ( Path 클래스의 메서드이다 )
    Files.size( Path path ) : 크기(byte)
    Files.isHidden ( Path path ) : 숨김여부
    ( File 객체의 isHidden 메서드와 숨김여부의 범위가 다르다 )
  • 다 사용한 Stream 의 자원은 반납한다.

응용02 -

  • request 객체로부터 정보를 가져오는 방법은 Stream 을 이용하는 방법밖에 없어 여기서는 외부에서 만든 라이브러리를 가져와 Stream을 얻어 InputStream 안에 넣고 Buffered 보조스트림을 이용하였다

  • 여기서는 한 번에 빠르게 데이터를 넣기 위해 파일 사이즈만큼의 배열을 생성하여 넣었다. 여기서 end of file 을 반환하는데 파일 크기 int 값이 출력이 된다.

  • Paths.get(경로) 로 경로를 지정한다.

  • Files.write(경로, 보낼크기, ... )로 파일을 어떻게 내보낼지 지정한다.
    CREATE : 파일이 존재하지 않으면 새 파일을 생성
    CREATE_NEW : 파일이 존재하면 새 파일을 생성
    READ : 읽기
    APPEND : 이어쓰기

  • 사용한 Stream 은 자원반납해준다.
    반면 nio 의 Channel 은 열고 닫을 필요가 없다.

0개의 댓글