hyeongwoo's blog

[Java] IO_(입출력스트림) 본문

JAVA

[Java] IO_(입출력스트림)

toribro 2024. 2. 2. 17:55

1. 자바의 입력출력클래스

   자바의 입력시 Scanner를 주로 사용한다. 하지만 Scanner는 상당히 느리기때문에 빠른 실행시간을 원하거나 코딩 테스트에서는 Scanner 대신 BufferedReader와 , InputStreamReader를 사용합니다.                                                                      출력시에도 System.out.Println()을 사용하는데 이 또한 느리기때문에 BufferedWriter와 OuputStreamReader를 사용합니다.

BufferedReader, BufferedWriter 와 InputStreamReader, OuputStreamReader 에 관해 알려면 자바 입출력 스트림에대해 알아야합니다.

스트림이란?

 자바에서 스트림은 데이터의 흐름입니다. 즉, 데이터가 이동하는 통로인데 자바에서는 InputStream 과 OutputStream 이라는 클래스가 통로 역할을 합니다. 모든 스트림은 단방향이고 각각의 장치마다 연결할 수 있는 스트림이 존재합니다. 하나의 스트림으로 입출력을 동시에 실행할 수 없으며 동시에 실행하려면 입력,출력 각각의 스트림이 필요합니다.

바이트 스트림

   데이터를 1바이트 단위로 전송하는 통로입니다. 단 방향의 좁은 통로이고 바이트(1byte)단위이기때문에 한글자가 2byte이상이되는 한글은 깨집니다. 

     XXXInputStream: 매체로부터 데이터를 입력받는 통로 (입력받아 자바 코드를 통해 메모리에 저장됩니다.)                         XXXOuputStream: 매체로부터 데이터를 출력하는 통로(메모리로부터 외부 저장소로 데이터를 내보냅니다.)

기반스트림: 외부매체와 직접적으로 연결하는 통로

최상위 클래스 하위 클래스
InputStream FileInputStream  
PipedInputStream  
FilterInputStream BufferedInputStream
DataInputStream
LineNumberInputStream
PushbackInputStream
ByteArrayInputStream  
SequenceInputStream  
StringBufferedInputStream  
ObjectInputStream

 
OuputStream FileOutputStream  
PipedOutputStream  
ByteArrayOutputStream  
ObjectOutputStream  

FilterOutputStream
PrintStream
BufferedOutputStream
DataOutputStream

 

InputStream 주요 메소드

 

리턴 타입 메소드 설명
int read() 입력 스트림으로부터 1바이트를 읽고 읽은 바이트 리턴
int read(byte[] b) 입력 스트림으로부터 읽은 바이트들을 매개 값으로 주어진 바이트 배열 b
저장하고 실제로 읽은 바이트 수 리턴
int read(byte[] b, int off, int len) 입력 스트림으로부터 len개의 바이트만큼 읽고 매개 값으로 주어진
바이트 배열 b[off]부터 len개까지를 저장, 그리고 실제로 읽은 바이트 수인
len개 리턴, 만약 len개를 모두 읽지 못 하면 실제로 읽은 바이트 수 리턴
void close() 사용한 시스템 자원 반납 후 입력 스트림을 닫음

 

OutputStream 주요 메소드

리턴 타입 메소드 설명
void write(int b) 출력 스트림으로 1바이트를 보냄
void write(byte[] b) 출력 스트림에 매개 값으로 주어진 바이트 배열 b의 모든 바이트를 보냄
void write(byte[] b, int off, int len) 출력 스트림에 매개 값으로 주어진 바이트 배열 b[off]부터 len개까지의
바이트를 보냄
void flush() 버퍼에 잔류하는 모든 바이트 출력
void close() 사용한 시스템 자원 반납 후 출력 스트림을 닫음

 

문자기반 스트림

 바이트스트림의 한계점을 보안한 스트림입니다. 바이트 스트림은 1byte단위로밖에 전송을 못해 한글은 깨지는 문제점이 있어 보완하고자 나온것이 문자기반 스트림입니다.

 XXXReader:입력용 스트림                                                                                                                                                       XXXWriter:출력용 스트림

 최상위 클래스 하위클래스
Reader BufferedReader LineNumberReader
CharArrayReader  
InputStreamReader FileReader
FilterReader PushbackReader
PipedReader  
StringReader  
Writer BufferedWriter  
CharArrayWriter  
OutputStreamWriter FileWriter
FilterWriter  
PipedWriter  
StringWriter  
FilterWriter  

 

   Reader 의 주요 메소드

리턴 타입 메소드 설명
int read() 입력 스트림으로부터 한 개의 문자를 읽고 리턴
int read(char[] c) 입력 스트림으로부터 읽은 문자들을 매개 값으로 주어진 문자 배열 c
저장하고 실제로 읽은 문자 수 리턴
int read(char[] c, int off, int len) 입력 스트림으로부터 len개의 문자만큼 읽고 매개 값으로
주어진 문자배열 c[off]부터 len개까지 저장, 실제로 읽은 문자 수인 len개 리턴
void close() 사용한 시스템 자원 반납 후 입력 스트림을 닫음

 

 

보조 스트림

기반 스트림만으로 부족했던 성능을 보다 향상시켜주는 스트림입니다. 기반 스트림에서 제공하지 않는 추가적인 메소드 제공/데이터 전송 속도를 향상시켜줍니다. 항상 기반 스트림과 함께 사용되어야합니다.

 

스트림 사용

문자열 입력,출력시

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
import java.lang.StringBuilder;

public class IO {
	
	public static void main(String[] args) {
		
		
		try(BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
			BufferedWriter output = new BufferedWriter(new OutputStreamWriter(System.out));
			) {
			String word=input.readLine();
			int a= Integer.parseInt(input.readLine());
			
			
			output.write(word);
			output.newLine();
			output.write(String.valueOf(a)+"\n");//스트링으로 변환이 필요
			output.flush();
			
			
			//공백처리시 BufferedReader 사용
			
			System.out.println("==========공백처리시 BufferedReader=========");
			
			String[]inputs=input.readLine().split(" ");
			for(String inp:inputs) {
				output.write(inp);
				output.newLine();
			}
			output.newLine();
			output.flush();
			
			
			
			//공백 처리시 토큰 사용
			System.out.println("==========token 사용=========");
			StringTokenizer st = new StringTokenizer(input.readLine());
			
		
		    while(st.hasMoreElements()) {
		    	output.write(st.nextToken());
		    	output.newLine();
		    }
		    output.newLine();
		    output.flush();
		    
		    System.out.println("==========builder 사용=========");
		    
		    StringTokenizer stb = new StringTokenizer(input.readLine());
		    StringBuilder builder =  new StringBuilder();
		    
		    String temp="";
		    while(stb.hasMoreElements()) {
		    	temp=stb.nextToken();
		    	builder.append(temp);
		    	output.write(temp);
		    	output.newLine();
		    }
		    output.flush();
		    output.write("Builder사용:"+builder.toString());
			
			
		} catch (IOException e) {
		
			e.printStackTrace();
		}	
	}
}

파일 입출력시

 기반스트림과 보조 스트림 사용

package com.kh.B_Stream;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ServeStream {


	//프로그램 -> 파일(출력)
	public void fileSave() {
		//FilewWriter :파일과 직접적으로 연결해서 2바이트 단위로 출력할 수 있는 기반 스트림
		
        //항상 보조스트림 생성자로 기반스트림객체가 들어가야한다.
		try(BufferedWriter bw =new BufferedWriter(new FileWriter("c_buffer.txt"));) {
			
			bw.write("반갑습니다.\n");
			bw.write("고마워요");
			bw.newLine();
			bw.write("ㅋㅋㅋㅋ");
			//파일을 닫아야지 내용이 파일에 올라간다.
			//bw.flush();//플러쉬 
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
	 public void fileRead() {
		
		//FileReader :파일과 연결해서 2바이트 단위로 데이터를 입력받을 수 있는 객체
        
		try(BufferedReader br =new BufferedReader(new FileReader("c_buffer.txt"));) {
	
			String value=null;
			while((value=br.readLine())!=null) {
				System.out.println(value);
			}
			
			 
		} catch (FileNotFoundException e) {
			
			e.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
	 }
	
    
    //객체를 사용한 파일 입출력
	//프로그램 -> 파일 출력
	 
	 public void objectSave() {
		 
		 //출력할 데이터 (Product 객체)
		 Product phone1=new Product("갤럭시1",100000);
		 Product phone2=new Product("갤럭시2",200000);
		 Product phone3=new Product("갤럭시3",300000);
		
		  //FileOutputStream :파일과 연결해서 1바이트 단위로 출력할 수 있는 기반 스트림
		 //ObjectOutputStream: 객체 단위로 출력할 수 있도록 도움을 주는 보조스트림(ObjectWriter 없음)
		 
		 try(ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream("d_project.txt"));) {
		
			 oos.writeObject(phone1);  //java.io.NotSerializableException 직렬화 예외
			 oos.writeObject(phone2);
			 oos.writeObject(phone3);
			 //객체에 직렬화 인터페이스 구현받고 사용
			 //다시 객체로 꺼낼수 있다.
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 
	 }
	 public void ObjectRead() {
		 
		 try(ObjectInputStream ois =new ObjectInputStream(new FileInputStream("d_project.txt"));) {
			 
			 while(true) {
		    	 System.out.println(ois.readObject()); 
		     }
			 
	     }catch(EOFException e) {//직접 예외를 찾아서 추가해주었다.
			System.out.println("파일을 다 읽어드렸습니다.");
		 }
		 catch (IOException e) {
			e.printStackTrace();
		 } catch (ClassNotFoundException e) {
			e.printStackTrace();
		 }
		 
	 }
}

 

'JAVA' 카테고리의 다른 글

[Java] 제네릭  (0) 2024.02.12
[Java] final  (0) 2024.02.10
[Java] None_Static영역과 Static영역  (0) 2024.02.02
[Java] 다형성  (0) 2024.01.27
[Java] 상속  (0) 2024.01.26