[Java] Stream

이주형·2023년 5월 21일
0

Java

목록 보기
9/10

📌 Stream

데이터를 외부와 읽고 쓸 수 있도록 제공되는 자바 클래스들

자바에서는 입력용 스트림으로 InputStream, 출력용 스트림으로 OutputStream을 제공한다.

데이터를 받아들이기 위해 사용하는 Stream을 InputStream,
데이터를 전송하기 위해 사용하는 Stream을 OutputStream이라고 생각하면 된다.


📌 FileStream

파일을 대상으로 데이터를 송수신하는 목적으로 사용하는 스트림이다.

  • FileOutputStream

    프로그램에서 파일로 데이터를 전송할 때 사용하는 스트림이다.
    데이터를 보내고자 하는 파일이 없으면 자동으로 생성된다.

// 데이터 저장
public static void saveData1() {

	try {
    	// 파일을 쓰기 위한 스트림을 생성한다.
		// 이미 파일이 있다면 파일의 내용을 모두 지우고 새로 쓴다.
		// 파일이 없다면 파일을 생성해준다.
		FileOutputStream fos = new FileOutputStream("test.txt");
        
        // 이미 파일이 있다면 기존 내용에 이어서 작성한다. (파일명 뒤에 true).
		// 파일이 없다면 파일을 생성해준다.
		// FileOutputStream fos = new FileOutputStream("test2.txt", true);

		// 쓰기 할 데이터를 준비한다.
		String value1 = "안녕하세요";

		// 데이터를 바이트 형태로 가공한다.
		byte[] data1 = value1.getBytes();

		// 데이터를 쓴다.
		fos.write(data1);
		// 출력버퍼에 데이터가 남아 있을 수도 있기 때문에
		fos.flush();
		// 닫아준다.
		fos.close();
		System.out.println("쓰기 완료");
        
		} catch (Exception e) {
		e.printStackTrace();
	}
}
  • FileInputStream

    파일의 데이터를 수신할 때 사용하는 스트림이다.
    데이터를 읽어올 파일이 없으면 예외가 발생한다.

// 읽어오기
public static void readData() {
	try {
		// FileInputStream을 생성한다.
		// 지정한 파일이 없으면 오류가 발생한다.
		FileInputStream fis = new FileInputStream("test2.txt");
        
		// 읽어올 데이터의 양(파일 용량 byte)를 구한다.
		int byteSize = fis.available();
			
		// 데이터를 담을 byte타입의 배열을 생성한다.
		byte [] byteArray = new byte[byteSize];
			
		// 데이터를 읽어온다.
		fis.read(byteArray);

		// 닫아준다.
		fis.close();
			
		// 문자열 객체를 생성한다.
		String str1 = new String(byteArray);
		System.out.println(str1);
			
	} catch (Exception e) {
		e.printStackTrace();
	}
}

📌 DataStream

기본 자료형 값을 byte 배열 형태로 변환해주는 역할을 하는 필터 스트림이다.

  • DataOutputStream
public static void savaData() {
	try {
		// 기본 스트림 생성
		FileOutputStream fos = new FileOutputStream("test3.txt");
        
		// 필터 스트림 생성
		// DataStream 생성
		DataOutputStream dos = new DataOutputStream(fos);

		// 쓴다.
		dos.writeInt(100);
		dos.writeDouble(11.11);
		dos.writeBoolean(true);
		dos.writeUTF("안녕하세요");

		// 닫는다.
		dos.flush();
		dos.close();
		fos.close();

		System.out.println("쓰기 완료");
        
	} catch (Exception e) {
		e.printStackTrace();
	}
}
  • DataInputStream
public static void readData() {
	try {
		// 기본 스트림 생성
		FileInputStream fis = new FileInputStream("test3.txt");
        
		// DataStream 생성
		DataInputStream dis = new DataInputStream(fis);

		int a1 = dis.readInt();
		double a2 = dis.readDouble();
		boolean a3 = dis.readBoolean();
		String a4 = dis.readUTF();

		// 닫는다
		dis.close();
		fis.close();

		System.out.println(a1);
		System.out.println(a2);
		System.out.println(a3);
		System.out.println(a4);
	} catch (Exception e) {
		e.printStackTrace();
	}
}

📌 2byte Stream

자바는 글자 하나를 2 byte를 사용하기 때문에 문자열 입출력 전용으로 사용하는 스트림들을 2byte stream이라고 부른다.
라인단위 입출력이 가능하고 문자열 인코딩 설정이 가능하다.

  • 2 바이트 출력 스트림
public static void saveData() {
	try {
		// 기본 스트림 생성
		FileOutputStream fos = new FileOutputStream("test4.txt");

		// OutputStreamWriter
		// 문자열 인코딩을 설정하는 필터 스트림
		OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8");

		// 출력 버퍼를 사용하는 필터 스트림
		BufferedWriter bw = new BufferedWriter(writer);

		// println, print, printf 를 사용할 수 있는 필터 스트림
		PrintWriter pw = new PrintWriter(bw);

		// 파일에 쓴다.
		pw.print("안녕하세요");
		pw.println("반갑습니다.");
		pw.printf("이름은 %s이고, 나이는 %d살 입니다.", "홍길동", 30);

		pw.flush();
		pw.close();
		bw.close();
		writer.close();
		fos.close();

		System.out.println("쓰기 완료");
	} catch (Exception e) {
		e.printStackTrace();
	}
}
  • 2 바이트 입력 스트림
public static void loadData() {
	try {
		FileInputStream fis = new FileInputStream("test4.txt");

		// 인코딩을 설정
		InputStreamReader irs = new InputStreamReader(fis, "UTF-8");

		// 입력 버퍼를 사용하는 필터 스트림
		BufferedReader br = new BufferedReader(irs);

		// 읽어온다.
		String str1 = null;
		StringBuffer buffer = new StringBuffer();

		do {
			// 한 줄을 읽어온다.
			str1 = br.readLine();
			if (str1 != null) {
				buffer.append(str1 + "\n");
			}
		} while (str1 != null);

		br.close();
		irs.close();
		fis.close();

		// StringBuffer의 문자열로 String을 만든다.
		String result = buffer.toString();
		System.out.println(result);
	} catch (Exception e) {
		e.printStackTrace();
	}
}

📌 Object Stream

객체를 입출력하기 위해 사용하는 스트림

public static void saveObject() {
	try {
		// 기본 스트림
		FileOutputStream fos = new FileOutputStream("test100.dat");
		// 객체 출력 스트림
		ObjectOutputStream oos = new ObjectOutputStream(fos);

		// 저장할 객체
		TestClass t1 = new TestClass(100, 200);
		TestClass t2 = new TestClass(300, 400);

		// 객체를 쓴다.
		oos.writeObject(t1);
		oos.writeObject(t2);

		oos.flush();
		oos.close();
		fos.close();

		System.out.println("객체 쓰기 완료");
	} catch (Exception e) {
		e.printStackTrace();
	}
}

public static void loadObject() {
	try {
		// 기본 스트림 생성
		FileInputStream fis = new FileInputStream("test100.dat");

		// 객체 읽기 스트림
		ObjectInputStream ois = new ObjectInputStream(fis);

		// 객체를 복원한다.
		TestClass t10 = (TestClass) ois.readObject();
		TestClass t20 = (TestClass) ois.readObject();

		ois.close();
		fis.close();

		t10.printData();
		t20.printData();

	} catch (Exception e) {
		e.printStackTrace();
	}
}

위에 코드를 보면 객체를 저장하고 복원하는 부분이 있다.
직렬화 하지 않은 객체를 스트림을 통해 입출력할 수 없기 때문에 직렬화를 해줘야 한다.

직렬화

메모리 상에 존재하는 객체를 출력할 수 있는 형태로 만드는 것

// 객체 직렬화를 위해 Serializable 인터페이스를 구현한다.
class TestClass implements Serializable {

	int memberA;
	int memberB;

	public TestClass(int memberA, int memberB) {
		this.memberA = memberA;
		this.memberB = memberB;
	}

	public void printData() {
		System.out.printf("memeberA : %d\n", memberA);
		System.out.printf("memeberB : %d\n", memberB);
	}
}

0개의 댓글