Java - 7. I/O: 바이트기반 스트림

갓김치·2020년 9월 25일
0

고급자바

목록 보기
22/47
post-thumbnail

Stream 스트림

  • 일차원적인 데이터의 흐름
  • 데이터를 목적지로 입출력하기 위한 방법
  • 자바의 스트림객체를 이용하여 스트림 형식으로 데이터를 읽고 쓸 수 있다
  • InputStream: 스트림 형식으로 데이터를 읽기 위해
  • OutputStream: 스트림 형식으로 데이터를 쓰기 위해

기본(기반)스트림

  • 기본에 충실, 인풋 아웃풋

보조스트림

  • 기본에 보조하는 추가적 기능을 가지는 스트림
  • 기본 없이는 쓸 수 없다: 보조스트림의 파라미터로 기본스트림을 넣어줘야함
  • Filter가 최상위 클래스

바이트 기반 스트림

  • 바이트 스트림은 1 byte를 입출력할 수 있는 스트림이다
  • 일반적으로 바이트로 구성된 파일, 즉 동영상 파일, 이미지 파일, 음악 파일을 처리하기에 적합한 스트림
  • InputStream, OutputStream 이라는 단어가 붙어있으면 바이트 스트림

InputStream

종류

  • Buffered~
    • Reader스트림에 버퍼기능을 제공하는 보조 스트림, 라인단위 읽기 가능
  • LineNumber~
    • Reader스트림에 버퍼기능을 제공하는 보조 스트림, 라인 번호를 유지
  • ByteArray~
    • 문자배열로부터 문자를 읽기 위한 스트림
  • File~
    • 파일로부터 바이트를 읽을 때 문자 단위 스트림으로 처리해 주는 스트림
  • Filter~
    • 필터(기능) 적용을 위한 추상클래스
  • Pushback~
    • 읽어들인 문자를 되돌리는(pushback) 기능을 제공하는 스트림
  • Piped~
    • Pipe 기능을 이용한 스트림 처리르 위한 기능을 제공
  • StringBuffer~
    • 문자열로부터 문자를 읽기 위해

메서드

  • read()
    • byte단위 (0~255)로 1바이트씩 자료를 읽어와 int형으로 반환
    • 더이상 읽어올 자료가 없으면 -1을 반환
  • read(byte[] b)
    • b 배열의 크기만큼 자료를 읽어와

OutputStream

종류

  • Buffered~
    • Writer 스트림에 버퍼기능을 제공하는 보조 스트림
  • ByteArray ~
    • 문자배열에 문자를 쓰기 위한
  • Filter ~
    • 파일에 문자 단위 스트림으로 쓰는 기능을 제공
  • File ~
    • 파일에 데이터를 쓸 때 문자 단위 스트림으로 처리해 주는 스트림
    • filter 랑 fiel이랑 뭔차인거지..?
  • Print~
    • Writer 스트림에 다양한 타입의 데이터 출력 기능을 제공하는 보조스트림
  • Piped~
    • PipedReader에 출력기능 제공하는 스트림

메서드

  • write(int data)
    • baos에 바이트 정보를 넣어준다
  • toByteArray()
    • 출력된 스트림 값들을 byte 배열로 변환해서 반환하는 메서드

예시

ByteArray ~ : byte단위로 작업하는 예시

  • T03_ByteArrayIOTest.java
  • main() throws IOException
byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
byte[] outSrc = null;

// 스트림 선언 및 객체 생성
ByteArrayInputStream bais = null; // 스트림 객체 선언
bais = new ByteArrayInputStream(inSrc); //객체 생성: 읽어들일 byte배열을 매개변수로 넣어줌

ByteArrayOutputStream baos = new ByteArrayOutputStream();

// read() 메서드 사용
// byte단위 (0~255)로 자료를 읽어와 int형으로 반환
// 더이상 읽어올 자료가 없으면 -1을 반환한다.

int data; // 읽어온 자료를 저장할 변수

while ((data = bais.read()) != -1) { // 더이상 읽을 자료가 없을때까지 무한루프
  baos.write(data); // 출력하기 - bais로 1바이트씩 읽은 바이트를 바로 baos 에 넣어줌
}

// 출력된 스트림 값들을 byte 배열로 변환해서 반환하는 메서드
outSrc = baos.toByteArray(); // byte[] outSrc에 담기 위해

System.out.println("inSrc => " + Arrays.toString(inSrc));
System.out.println("outSrc => " + Arrays.toString(outSrc));

// 스트림 객체 닫아주기
bais.close();
baos.close();

ByteArray ~ : 4byte씩 작업하는 예시

  • T04_ByteArrayIOTest.java
  • temp 이용해 효율 높임. 한번에 4개씩 write
  • main() 내에서 실행
byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
byte[] outSrc = null;

byte[] temp = new byte[4]; // 자료 읽을 때 사용할 배열

ByteArrayInputStream bais = new ByteArrayInputStream(inSrc);
ByteArrayOutputStream baos = new ByteArrayOutputStream();

방법1: available()

  • available(): 읽어올 수 있는 byte수를 반환
  • 잘 쓰이지 않는 방법임
try {
  while(bais.available() > 0) {
    bais.read(temp); // temp 배열 크기만큼 inSrc의 자료를 읽어와 temp배열에 저장
    baos.write(temp): // temp배열의 내용을 outSrc에 저장(=데이터 출력)한다.

    System.out.println("temp : " + Arrays.toString(temp));
  }
  System.out.println("baos.toByteArray()하기전 outSrc => " + outSrc);

  outSrc = baos.toByteArray();

  System.out.println("inSrc => " + Arrays.toString(inSrc));
  System.out.println("outSrc => " + Arrays.toString(outSrc));

  // 스트림 객체 닫아주기
  bais.close();
  baos.close();
} catch (IOException e) {
  e.printStackTrace();
}
  • 결과: 중복되어서 나옴

방법1-2: available() + int len = bais.read(temp)

try {
  while(bais.available() > 0) {
    
    // 실제 읽어온 byte 개수 반환
    int len = bais.read(temp);
    
    // temp배열의 내용 중 0번째부터 len개수만큼 출력
    baos.write(temp, 0, len); // 배열명, 기준인덱스, 읽을 갯수
    
    System.out.println("temp : " + Arrays.toString(temp));
  }
  System.out.println("baos.toByteArray()하기전 outSrc => " + outSrc);

  outSrc = baos.toByteArray();

  System.out.println("inSrc => " + Arrays.toString(inSrc));
  System.out.println("outSrc => " + Arrays.toString(outSrc));

  // 스트림 객체 닫아주기
  bais.close();
  baos.close();
} catch (IOException e) {
  e.printStackTrace();
}
  • 결과: 중복값 출력 x, 실제 데이터 갯수만큼만 출력됨

방법2: while((len = bais.read(temp)) != -1)

  • 잘 쓰이는 방법
```java
try {
int len; // 실제 읽어온 byte수를 반환
while((len = bais.read(temp)) != -1) {
    // temp배열의 내용 중 0번째부터 len개수만큼 출력
    baos.write(temp, 0, len); // 배열명, 기준인덱스, 읽을 갯수
    
    System.out.println("temp : " + Arrays.toString(temp));
  }
  System.out.println("baos.toByteArray()하기전 outSrc => " + outSrc);

  outSrc = baos.toByteArray();

  System.out.println("inSrc => " + Arrays.toString(inSrc));
  System.out.println("outSrc => " + Arrays.toString(outSrc));

  // 스트림 객체 닫아주기
  bais.close();
  baos.close();
} catch (IOException e) {
  e.printStackTrace();
}
  • 결과(방법1-2랑 같음)
profile
갈 길이 멀다

0개의 댓글