본문 바로가기

Java

Java IO (기반 Stream)

Stream (기반 Stream)

  • 데이터 운반 연결통로
  • 단방향 통신만 가능
    • 입출력 동시에 수행하려면 2개의 스트림 필요

 

  • 출력 스트림 : 프로그램 기준에서 나가는 스트림
  • 입력 스트림 : 프로그램 기준으로 들어오는 스트림.


바이트 기반 스트림 - InputStream, OutputStream

  • 바이트 단위로 데이터를 전송
    • 입출력 단위 : 1Byte

1. InputStream, OutputStream

InputStream의 하위 클래스

InputStream주요 메소드

void close()
  • 스트림을 닫음
    • 사용하고 있던 자원 반환
abstract int read()
  • 입력 스트림으로부터 1바이트를 읽고,
    읽은 바이트를 리턴.
int read (byte [] b)
  • 입력 스트림으로부터 읽은 바이트들을 b 바이트 배열에 저장
    실제로 읽은 바이트 수를 리턴.
  • 반환값 <= 배열의 크기
int read(byte [] b, int off, int len)
  • 최대 len개의 byte를 읽어서, 배열 b의 지정된 위치(off)부터 저장

 


OutputStream의 하위클래스

OutputStream 주요 메소드

void close()
  • 사용하고 있던 자원 반환
  • 출력스트림 닫음
void flush()
  • 버퍼가 있는 출력스트림의 경우에만 의미 있음
  • 버퍼에 잔류하는 모든 바이트를 출력.
    • 스트림의 버퍼에 있는 모든 내용을 출력소스에 씀.
abstract void write (int b)
  • 주어진 값을 출력소스에 씀
  • 출력스트림으로부터 1바이트를 보냄.
void write(byte [] b)
  • 주어진 배열 b에 저장된 모든 내용을 출력소스에 씀.
  • 출력스트림으로부터 주어진 바이트 배열 b의 모든 바이트를 보냄.
void write(byte [] b, int off, int len)
  • 주어진 배열 b에 저장된 내용 중에서 off번째부터 len개만큼 읽어서 출력소스에 씀.

 

 

 

 

2. ByteArrayInputStream, ByteArrayOutputStream

  • 바이트배열의 데이터를 입출력할 때, 사용되는 스트림.
    • 다른 곳에 입출력하기 전, 데이터를 잠시 바이트배열에 담아서 변환 등의 작업
  • close() 사용 안해도 됨
    • 바이트 배열이 사용하는 자원 : 메모리 뿐.
      • 가비지컬렉터에 의해 자동적으로 자원 반환.

 

입출력 스트림 예제

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;

public class IOEx1 {
	public static void main(String[] args) {
		byte [] inSrc = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
		byte [] outSrc = null;
		
		ByteArrayInputStream input = null;
		ByteArrayOutputStream output = null;
		
		input = new ByteArrayInputStream(inSrc);	//ByteArrayInputStream 생성, inSrc를 사용하는, 
		output = new ByteArrayOutputStream();
		
		int data = 0;
		
		while( (data = input.read() ) != -1) {		//int형 data에  ByteArrayInputStream으로부터 데이터를 byte로 읽어들임.
			output.write(data);				//void write(int b)
		}
		
		outSrc = output.toByteArray();		//스트림의 내용을 byte배열로 반환.
		
		System.out.println("Input Source : " + Arrays.toString(inSrc));
		System.out.println("Output Source : " + Arrays.toString(outSrc));
	}
}
  • 1Byte씩 읽고 씀.
    • 작업효율 떨어짐.
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;

public class IOEx2 {
	public static void main(String[] args) {
		byte [] inScr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
		byte [] outScr = null;
		byte [] temp = new byte[10];
		
		ByteArrayInputStream input = null;				//ByteArrayIntputStrem형 input 선언.
		ByteArrayOutputStream output = null;    		//ByteArrayOutputStream형 output 선언.
		
		input = new ByteArrayInputStream(inScr);		//inScr를 이용해서 ByteArrayInputStream생성.
		output = new ByteArrayOutputStream();			//ByteArrayOutputStream 생성.
		
		input.read(temp, 0, temp.length);			//temp배열에서 temp[0] ~ temp길이만큼 읽어들임.
		output.write(temp, 6, 4);						//temp[7], temp[8], temp[9], temp[10]의 데이터를 읽어옴.
		
		outScr = output.toByteArray();	//temp로부터 읽어들인 데이터를 ByteArray로 변환. ->outScr에 대입.
		
		System.out.println("Input Source : " + Arrays.toString(inScr));
		System.out.println("temp             : " + Arrays.toString(temp));
		System.out.println("Output Source : " + Arrays.toString(outScr));
	}
}
  • temp길이만큼 읽어들임.
  • temp[7] ~ temp길이까지 읽어옴.
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class IOEx3 {
	
	public static void main(String[] args) {
		byte [] inSrc = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
		byte [] outSrc = null;
		byte [] temp = new byte[4];
		
		ByteArrayInputStream input = new ByteArrayInputStream(inSrc);		//inScr를 통해 ByteArrayInputStream선언 및 생성.
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		
		System.out.println("Input Source : " + Arrays.toString(inSrc));
		
		try {
			while(input.available() >0) {					//ByteArrayInputStream으로부터 읽을 수 있는 바이트의 숫자를 정수형으로 반환.
				input.read(temp);			//InputStream으로부터 읽어와서 temp에 저장.
				output.write(temp); 		//읽어온 데이터를 temp에 씀.
				System.out.println("temp : " + Arrays.toString(temp));
				
				outSrc = output.toByteArray();
				printArrays(temp, outSrc);
				System.out.println();
			}
		}catch(IOException e) {}	
		
	}
	
	static void printArrays(byte [] temp, byte [] outSrc) {
		System.out.println("temp              : " + Arrays.toString(temp));
		System.out.println("Output Source : " + Arrays.toString(outSrc));
	}
}

  • 기존의 temp {4, 5, 6, 7}에 남은 input {8, 9} 2개 요소만 넣기 때문에
    temp = {8, 9, 6, 7}

 

 

3. FileInputStream과 FileOutputStream

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopy {
	public static void main(String[] args) {
		try {
			FileInputStream fis = new FileInputStream(args[0]);
			FileOutputStream fos = new FileOutputStream(args[1]);
			
			int data = 0;
			while((data = fis.read()) != -1) {		//FileIntputStream으로부터 데이터를 바이트로 읽어옴.	/1Byte = 8bit = 숫자 표현 범위 : (-128 ~ 127) = (0 ~ 255) //데이터 범위 : -1~255 (-1 : 입력값이 더 이상 없을 때) // 따라서 int형 값(-2,147,483,648 ~ 2,147,483,647)으로 반환.
				fos.write(data);
			}
		}catch (IOException ex) {
			System.out.println(ex);
		}
	}
}
  • read()가 1Byte씩 파일의 데이터를 읽어옴
    • 1Byte = 8bit = 숫자 표현 범위 : -128 ~ 127
      • 따라서 비록 숫자 표현 범위가 확 커지긴 하지만 (-2,147,483,648 ~ 2,147,483,647)인 int형으로 반환.

 

 


문자기반 스트림 - Reader, Writer

  • 문자데이터 입출력 시, 사용
    • 2Byte기반으로 데이터 처리.
      • 바이트 기반 스트림 : 1Byte이므로,  문자 char형(2Byte)읽는데 문제 있음.

종류

바이트기반 스트림 (1Byte) 문자기반 스트림 (2Byte)
FileInputStream
FileOutputStream
FileReader
FileWriter
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
StringBufferInputStream (deprecated) <- 퇴물이 된 기능
StringBufferOutputStream (deprecated)
StringReader
StringWriter
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWirter
FilterInputStream
FilterOutputStream
FilterReader
FilterWirter
PrintStream  (ore Java에서 사용) PrintWriter (sublet.jsp에서 사용)
                   (UTF-8에서 사용)

 

 

바이트기반 스트림 메소드 vs 문자기반 스트림 메소드

 

'Java' 카테고리의 다른 글

클래스 종류  (0) 2020.10.05
Eclipse 단축키  (0) 2020.09.11
RandomAccessFile  (0) 2020.09.11
Java IO (보조 Stream)  (0) 2020.09.10