[Java] 12_IO(보조 스트림을 이용한 객체, 객체배열 단위 입출력)

2022. 8. 17. 10:07·📗 self-study/📗 KH정보교육원 당산지원

12_IO(입출력)

 

 보조 스트림을 이용하면 파일 입출력을 객체 단위로 활용 가능함

=> 이는 컴퓨터에 기록할 용도이지 사람이 읽을 용도가 아니므로 파일을 열었을 때 글자가 깨지는 현상 자주 나올 수 있음!

 

ObjectDao클래스에 Phone 클래스의 객체를 넣어서 출력하고 싶다!

 

프로그램 ---> 외부 매체(파일)
 출력

package com.kh.chap04.assist.part02.object.model.dao;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

import com.kh.chap04.assist.part02.object.model.vo.Phone;

public class ObjectDao {
	
	public void fileSave() {
		
		// (기반) FileOutputStream: 파일에 데이터를 1byte 단위로 출력할 수 있는 기반 스트림
		// + 
		// (보조) ObjectOutputStream : 객체 단위로 출력할 수 있는 보조 스트림
		// => "1bye" 짜리 보조 "출력" 스트림에는 "1bye" 짜리 기반 "출력" 스트림을 써야 함
		
		// 테스트용 객체 생성
		Phone ph = new Phone("아이폰", 1300000);
		
		// 0. 스트림 변수 선언 및 null로 초기화
		
		ObjectOutputStream oos = null;
		
		// 1. 스트림 객체 생성(== 연결 통로를 만들겠다)
		
		try {
			oos = new ObjectOutputStream(new FileOutputStream("phone.txt"));
			
			// 2. 출력: ObjectOutputStram 객체에서 제공하는 writeObject() 메소드 사용
			oos.writeObject(ph);
			
			// 3. 자원 반납(== 연결통로를 끊겠다) => 반드시 finally 블럭 안에 작성
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 3. 자원 반납 (반드시)
			try {
				oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
        
		}
}

직렬화 선언을 하지 않으면 객체를 파일로 내보낼 때 NotSerializableException이 발생
=> 1byte짜리 좁은 통로로 큰 객체가 지나갈 수 없기 때문에 가로로 배열해 주는 과정: 직렬화

 

Phone클래스에 직렬화 선언해 주고 import만 해 주면 오류 해결 됨!

import java.io.Serializable;

public class Phone implements Serializable { // 직렬화 선언

저장 후 재실행 해 보면

여전히 문자가 깨어진 듯하긴 하지만! 잘 기록이 된 상태임

=> 해당 파일은 사람이 읽기 위한 파일이 아닌 프로그램상으로 필요한 데이터를 사용할 때 두고두고 기록할 용도이기 때문에 깨지는 건 큰 상관 없음

=> 하지만 여전히 의심스럽다면ㅡㅡ? 입력을 해 보면 됨!

 

프로그램 <--- 외부 매체(파일)
입력

	public void fileRead() {
		
		// FileInputStream: 파일로부터 데이터를 1byte 단위로 읽어들이기 위해 사용되는 기반 스트림
		// +
		// ObjectInputStream: 객체 단위로 입력받기 위해 사용되는 보조 스트림
		
		// 0. 스트림 변수 선언 및 null로 초기화
		ObjectInputStream ois = null;
		
		// 1. 스트림 객체 생성(== 연결 통로를 만들겠음)
		
		try {
			ois = new ObjectInputStream(new FileInputStream("phone.txt"));
			
			// 2. 입력: ObjectInputStream 객체에서 제공하는 readObject() 메소드 사용

				Phone ph = (Phone)ois.readObject(); // 다형성에 의해 DownCasting
				System.out.println(ph);
			
			// 3. 연결 통로 끊기(반드시) => finally 블럭에
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		} finally {
			try {
				ois.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
    
  // 출력물
  name: 아이폰, price: 1300000

=> 입력이 잘됨!

 

코드를 더 줄이고 싶다면?

try ~ with ~ resource 구문 버전

		try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("phone.txt"))) {
			
			Phone ph = (Phone)ois.readObject();
			System.out.println(ph);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

 

배열도 가능하지 않을까?

 

프로그램 ---> 외부매체(파일)

출력

	public void fileSave() {
		
		// FileOutputStram + ObjectOutputStream (1byte짜리 좁은 통로)
		
		// 테스트용 객체 배열
		Phone[] arr = new Phone[3]; // [0] [1] [2]
		
		// 테스트용 데이터 담기
		arr[0] = new Phone("아이폰", 1300000);
		arr[1] = new Phone("갤럭시", 1500000);
		arr[2] = new Phone("플립폰", 2000000);
		
		// try ~ with ~ resource 구문으로 한 큐에 생성
		
		try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("phones.txt"))){
			
			
			// 출력: ObjectOutputStream 객체에서 제공하는 writeObject() 메소드 사용
			// oos.writeObject(arr[0]);
			// oos.writeObject(arr[1]);
			// oos.writeObject(arr[2]);
			
			// 반복문 이용해서 내보내기
			for(int i =0; i < arr.length; i++) {
				oos.writeObject(arr[i]);
				System.out.println(arr[i]);
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
    
 // 출력물
 name: 아이폰, price: 1300000
name: 갤럭시, price: 1500000
name: 플립폰, price: 2000000

 

프로그램 <--- 외부매체(파일)

입력

public void fileRead() {
		
		// FileInputStream + ObjectInputStream
		
		Phone[] ph = new Phone[3];
		
		try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("phones.txt"))) {
			
			// toString() 메소드를 오버라이딩 했기 때문에 굳이 형변환 하지 않고 바로 출력해 보기
			// System.out.println(ois.readObject() /* .toString() */);
			// System.out.println(ois.readObject());
			// System.out.println(ois.readObject());
			// EOFExeption(End of file): 파일 내용이 끝났음에도 자꾸 출력하고자 할 때 발생하는 오류
			// => IOException의 자식임
			// System.out.println(ois.readObject());
			
			// EOFException이 발생할 때까지만 반복을 돌리기
			// 예측 불가능한 오류이기 때문에 정확한 조건을 세울 수 없음
			
			while (true) { // 그래서 일단은 무한 반복
				System.out.println(ois.readObject());
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (EOFException e) { // while문 무한반복 하다가 언젠가 EOFException이 발생하는 순간 이쪽으로 들어옴
			System.out.println("파일을 다 읽었습니다.");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} 
		
		// catch문은 한 구문이 출력된 후 try ~ catch문을 빠져나오기 때문에 후에는 프로그램 종료가 출력됨
		System.out.println("프로그램 종료");
	}

 

사용자가 원하는 파일 이름을 받아서 출력하고 싶다면

// Run클래스의 fileSave(매개변수) 이용

ObjectsDao ods = new ObjectsDao();
		
		 ods.fileSave("phones.txt");
         
// ObjectsDao 클래스에서 매개변수(String fileName) 추가

public void fileSave(String fileName) {

phones.txt는 예시로 넣은 거고, 실제로는 스캐너를 이용하여 사용자의 입력을 받아서 넣어야겠져

 

 

저작자표시 (새창열림)
'📗 self-study/📗 KH정보교육원 당산지원' 카테고리의 다른 글
  • [8/18 시험 대비]
  • [Java] 13_네트워크(Network)
  • [Java] 12_입출력[바이트 기반 스트림(== 좁은 통로)과 문자 기반 스트림(== 넓은 통로)의 입출력, 보조 스트림의 개요 및 입출력]
  • [Java] 12_입출력(Input/Output의 개요)
천재강쥐
천재강쥐
  • 천재강쥐
    디버거도 버거다
    천재강쥐
  • 전체
    오늘
    어제
    • Category (467)
      • 진짜 너무 궁금한데 이걸 나만 몰라...? (0)
      • 💾 Portfolio (2)
      • 🐤 CodingTest (28)
        • Java (20)
        • ᕕ(ꐦ°᷄д°᷅)ᕗ❌ (5)
      • 🚀 from error to study (142)
        • AI (1)
        • Cloud (2)
        • DB (12)
        • Front-End (16)
        • Github (14)
        • Java (39)
        • Mac (7)
        • Normal (29)
        • Server (22)
      • 📘 certificate (44)
        • 📘 리눅스마스터1급 (1)
        • 📘⭕️ 정보처리기사 (40)
        • 📘⭕️ SQLD (3)
      • 📗 self-study (234)
        • 📗 inflearn (35)
        • 📗 생활코딩 (8)
        • 📗 KH정보교육원 당산지원 (190)
      • 🎨 Scoop the others (0)
        • 📖 Peeking into other people.. (0)
        • 🇫🇷 (0)
        • 📘⭕️ 한국사능력검정시험 심화 (11)
        • 오블완 (4)
  • 인기 글

  • hELLO· Designed By정상우.v4.10.1
천재강쥐
[Java] 12_IO(보조 스트림을 이용한 객체, 객체배열 단위 입출력)
상단으로

티스토리툴바