I/O

YongJun·2023년 9월 19일

JAVA

목록 보기
24/24
post-thumbnail

I/O 란?

  • Input과 Output의 약자로 입출력을 의미함
  • 입출력의 간단한 예로 키보드로 텍스트를 입력하고, 모니터로 입력한 텍스트를 출력하는 것임

스트림(stream)

  • 어느 한쪽에서 다른 쪽으로 데이터를 보낼려면 일종의 다리 역할을 하는 친구가 필요하다 그 친구가 바로 스트림이다.
  • 클라이언트나 서버 간에 출발지 목적지로 입출력하기 위한 데이터가 흐르는 통로를 말한다.
  • 추가적으로 스트림의 어원은 연속적인 데이터의 흐름을 물에 비유하여 붙여진 이름이라는데,,,여러 가지로 유사한 점이 많다고 한다.
    가장 큰 특징으로는 물이 한뱡향으로 흐르는 것과 같이 스트림은 단방향통신만 가능하다. 즉, 하나의 스트림으로 입출력을 동시에 처리할 수 없다.
    만약! 입출력을 동시에 처리하고 싶으면 입력 스트림 1개, 출력 스트림 1개 총 2개의 스트림을 생성하면 된다.

Java I/O 패키지

데이터 스트림, 직렬화 및 파일 시스템을 통한 시스템 입력 및 출력 제공
즉, Java I/O 패키지 안에는 파일 입출력과 관련된 클래스들로 구성되어있다.

직렬화(serialize)란 자바 언어에서 사용되는 Object 또는 Data를 다른 컴퓨터의 자바 시스템에서도 사용 할수 있도록 바이트 스트림(stream of bytes) 형태로 연속전인(serial) 데이터로 변환하는 포맷 변환 기술을 일컫는다. 그 반대 개념인 역직렬화는(Deserialize)는 바이트로 변환된 데이터를 원래대로 자바 시스템의 Object 또는 Data로 변환하는 기술이다.
이를 시스템적으로 살펴보면, JVM의 힙(heap) 혹은 스택(stack) 메모리에 상주하고 있는 객체 데이터를 직렬화를 통해 바이트 형태로 변환하여 데이터베이스나 파일과 같은 외부 저장소에 저장해두고, 다른 컴퓨터에서 이 파일을 가져와 역질렬화를 통해 자바 객체로 변환해서 JVM 메모리에 적재하는 것으로 보면 된다.

바이트 단위 스트림

자바는 스트림의 기본 단위를 바이트로 두고 있기 때문에, 네트워크, 데이터베이스로 전송하기 위해 최소 단위인 바이트 스트림으로 변환하여 처리한다.

  • InputStream, OutputStream 둘다 바이트 기반 입출력 스트림의 최상위 클래스로 추상 클래스이다. 관련된 모든 바이트 기반 입출력 스트림은 이 클래스를 상속받아서 만들어 진다.
  • 바이트단위로 데이터를 전송하며 입출력 대상에 따라 제공하는 클래스가 다르다.
  • 그림, 멀티미디어, 문자 등 모든 종류의 데이터를 주고 받을 수가 있다

InputStream 클래스에 정의된 메소드

OutputStream 클래스에 정의된 메소드

예제1 (BufferedInputStream, read())

package io;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;


public class ByteStream {

	public static void main(String[] args) throws IOException {
			/*
            ★보조 스트림★
              스트림의 기능을 보완하기 위해 나온 녀석이다.(입출력 성능 속도 향상, 데이터 포멧 등)
              실제 데이터를 주고 받지 않는다.
              데이터를 주고 받을 수 없기 때문에 먼저 스트림을 생성한 후 사용해야 한다.
              
			BufferedInputStream/BufferedOutputStream은 스트림의 입출력 효율을 높이기 위해 버퍼를 사용하는 보조스트림이다. 
			한 바이트씩 입출력하는 것 보다는 버퍼를 이용해서 한 번에 여러 바이트를 입출력하는 것이 빠르기 때문에 대부분의 입출력 작업에 사용된다.
			*/
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("data.txt")));
			int data;
			
			while( (data = bis.read()) != -1){  
				System.out.print((char)data+" ");
			}
			System.out.println();
	}

}

예제2 (BufferedInputStream, read(byte b[], int start, int length))

package io;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class ByteStream2 {

	public static void main(String[] args) {
		try {
			File file = new File("data.txt");
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
			int size = (int)file.length(); //파일 크기
			byte[] b = new byte[size];
			
			bis.read(b, 0, size);
			bis.close();
			System.out.println(new String(b)); //byte[] -> String 변환
		} catch (IOException e) {		
			e.printStackTrace();
		}

	}

}

예제3 (DataOutputStream / DataInputStream)

package io;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class DataStream {

	public static void main(String[] args) {
		try {
			/*
			DataOutputStream / DataOutputStream은 int, float 와 같은 기본형 단위(primitive type)로 데이터를 처리하는 보조 스트림이다.
			 */
			//파일 출력
			DataOutputStream dos = new DataOutputStream(new FileOutputStream("result.txt"));
			
//			FileOutputStream fos = new FileOutputStream("result.txt");
//			DataOutputStream dos = new DataOutputStream(fos);
			
			dos.writeUTF("홍길동");
			dos.writeInt(25);
			dos.writeDouble(185.3);
			
			dos.close();
		
			
			//파일 읽기
			DataInputStream dis = new DataInputStream(new FileInputStream("result.txt"));
			
			String name = dis.readUTF();
			int age = dis.readInt();
			double height = dis.readDouble();
			
			
			System.out.println("이름 = "+name);
			System.out.println("나이 = "+age);
			System.out.println("키 = "+height);	
		} catch(FileNotFoundException e){
			e.printStackTrace();
		}
		catch(IOException e) {
			e.printStackTrace();
		}
	}
}

예제4 (DataOutputStream / DataInputStream)

package io;

import java.io.Serializable;
/*
★ 객체 직렬화(Serializable)
객체는 파일이나 네트워크로 전송이 안된다
객체를 byte[] 변환시켜서 전송해야한다
*/
public class PersonDTO implements Serializable{
	private String name;
	private int age;
	private double height;
	
	public PersonDTO(String name, int age, double height) {
		super();
		this.name = name;
		this.age = age;
		this.height = height;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}	
    
}
package io;

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

public class ObjectMain {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		PersonDTO dto = new PersonDTO("홍길동",25,185.3);
		
		//파일로 출력
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("result2.txt"));
		oos.writeObject(dto);
		oos.close();
		
		//파일의 내용을 읽어오기
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("result2.txt"));
		PersonDTO dto2 = (PersonDTO)ois.readObject(); //객체를 읽어오기 , 자식 = (자식)부모
		
		System.out.println("이름 = "+dto2.getName());
		System.out.println("나이 = "+dto2.getAge());
		System.out.println("키 = "+dto2.getHeight());
		
		ois.close();
	}
}

문자 단위 스트림

  • Reader, Writer 둘다 문자 데이터 기반 입출력의 최상위 클래스이다. 관련된 모든 문자 기반 입출력은 이 클래스를 상속받아서 만들어 진다.
  • 문자데이터를 입출력할 때 사용하는 문자기반의 스트림이다.
  • 오로지 문자 데이터를 주고 받기 위해 특화되어있다.

Java I/O 패키지 주요 클래스 및 설명

profile
개(발자어)린이

0개의 댓글