2021. 2. 19.

13주차 과제: I/O

https://github.com/whiteship/live-study/issues/13

목표

자바의 Input과 Ontput에 대해 학습하세요.

학습할 것 (필수)

  • 스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O
  • InputStream과 OutputStream
  • Byte와 Character 스트림
  • 표준 스트림 (System.in, System.out, System.err)
  • 파일 읽고 쓰기


스트림 (Stream) / 버퍼 (Buffer) / 채널 (Channel) 기반의 I/O

스트림

  • 입력에서 출력으로 흐르는 흐름 (단방향)
  • FIFO(First In First Out)
  • 블록킹 방식만 지원(동기)
  • 입력 스트림, 출력 스트림 필요

버퍼

  • 기본 데이터 타입을 저장할 수 있는 저장소
  • 일정한 양이 채워지면 데이터를 전송

채널

  • 쌍방향 통로
  • 데이터를 주고받을 때 버퍼를 사용
  • 입력과 출력을 위한 별도의 채널 불필요

NIO (New I/O, Non-blocking I/O)

  • 자바 1.4 버전부터 추가된 API
  • Buffer(버퍼)를 사용
  • 비동기 방식 지원
  • 스트림이 아닌 채널(Channel)을 사용


InputStream과 OutputStream

InputStream

  • 바이트 단위 입출력을 위한 최상위 입력 스트림 클래스
  • FileInputStream, BufferedInputStream, DataInputStream

표 출처: https://coding-factory.tistory.com/281


OutputStream

  • 바이트 단위 입출력을 위한 최상위 입력 스트림 클래스
  • FileOutputStream, PrintStream, BufferedOutputStream, DataOutputStream

표 출처: https://coding-factory.tistory.com/281


Byte와 Character 스트림

Byte Stream

  • 바이트 기반 입출력 스트림
  • 입출력 단위가 1byte
  • FileInputStream/FileOutputStream: 파일
  • ByteArrayInputStream/ByteArrayOutputStream: 메모리(byte배열)
  • PipedInputStream/PipedOutputStream: 프로세스(프로세스간 통신)
  • AudioInputStream/AudioOutputStream: 오디오 장치

Character Stream

  • 문자(2 byte)를 위한 스트림
  • 모든 문자 스트림 클래스는 Reader / Writer의 자손
  • 스트림 클래스로 수행 된 입력 및 출력은 로컬 문자 집합과 자동으로 변환

https://docs.oracle.com/javase/tutorial/essential/io/charstreams.html


표준 스트림 (System.in, System.out, System.err)

콘솔을 통한 데이터 입력과 출력을 위한 스트림

  • System.in - 콘솔로부터 데이터 입력받는데 사용
  • System.out - 콘솔 화면에 문자열 출력을 위한 용도
  • System.err - System.out과 같이 콘솔 문자열 출력이지만 버퍼링을 지원하지 않고 빨간색으로 출력된다.


파일 읽고 쓰기

채널 I/O를 사용한 파일 읽고 쓰는 방법

스트림 I/O가 한 번에 문자를 읽는 동안 채널 I/O는 한 번에 버퍼를 읽습니다. ByteChannel 인터페이스는 기본으로 read write 기능을 제공합니다. SeekableByteChannel은 ByteChannel의 위치를 유지하거나 변경할 수 있는 기능이 있습니다. 또한 채널과 관련된 파일 자르기 및 파일 크기 쿼리를 지원합니다.

채널 I/O를 읽고 쓰는 방법에는 두 가지가 있습니다.

  • newByteChannel(Path, OpenOption...)
  • newByteChannel(Path, <Set? extends OpenOption>, FileAttribute<?>...)

다음 코드 조각은 파일을 읽고 표준 출력으로 인쇄합니다.

// Defaults to READ
try (SeekableByteChannel sbc = Files.newByteChannel(file)) {
    ByteBuffer buf = ByteBuffer.allocate(10);

    // Read the bytes with the proper encoding for this platform.  If
    // you skip this step, you might see something that looks like
    // Chinese characters when you expect Latin-style characters.
    String encoding = System.getProperty("file.encoding");
    while (sbc.read(buf) > 0) {
        buf.rewind();
        System.out.print(Charset.forName(encoding).decode(buf));
        buf.flip();
    }
} catch (IOException x) {
    System.out.println("caught exception: " + x);

UNIX 및 기타 POSIX 파일 시스템 용으로 작성된 다음 예제는 특정 파일 권한 집합을 사용하여 로그 파일을 만듭니다. 이 코드는 로그 파일을 만들거나 이미있는 경우 로그 파일에 추가합니다. 로그 파일은 소유자에 대한 읽기 / 쓰기 권한과 그룹에 대한 읽기 전용 권한으로 생성됩니다.

import static java.nio.file.StandardOpenOption. *; 
import java.nio. *; 
import java.nio.channels. *; 
import java.nio.file. *; 
import java.nio.file.attribute. *; 
import java.io. *; 
import java.util. *; 

public class LogFilePermissionsTest { 

  public static void main (String [] args) { 
  
    // 파일에 추가하기위한 옵션 세트를 만듭니다. 
    Set <OpenOption> options = new HashSet<OpenOption>(); 
    options.add(APPEND); 
    options.add(CREATE); 

    // 사용자 지정 권한 속성을 만듭니다. 
    Set <PosixFilePermission> perms = 
      PosixFilePermissions.fromString ("rw-r-----"); 
    FileAttribute <Set<PosixFilePermission>>
      PosixFilePermissions.asFileAttribute(perms); 

    // 문자열을 ByteBuffer로 변환합니다. 
    String s = "Hello World!"; 
    byte data[] = s.getBytes (); 
    ByteBuffer bb = ByteBuffer.wrap(data); 
    
    경로 파일 = Paths.get ("./permissions.log"); 

    try (SeekableByteChannel sbc = 
      Files.newByteChannel (file, options, attr)) { 
      sbc.write (bb); 
    } catch (IOException x) { 
      System.out.println ("예외 발생: "+ x); 
    } 
  } 
}

출처: https://docs.oracle.com/javase/tutorial/essential/io/file.html

댓글 없음:

댓글 쓰기