국비 19-2

냐아암·2023년 5월 12일
0

국비

목록 보기
26/114

IO

  • Input: 입력 -> 외부에서 내부로 데이터가 들어오는 것

  • Output: 출력 -> 내부에서 외부로 데이터가 나가는 것

  • Stream: 입/출력 통로 역할(데이터가 흘러가는 통로)
    기본적으로 Stream은 단방향

Stream을 쓸 때 try - catch - finally 필수
--> 닫을 때 finally 안에 넣기 위해, 즉 try 괄호 밖에서 쓰기 위해 변수만 제일 위에 따로 선언


객체 입출력

  • ObjectXXXStream: 객체를 파일 또는 네트워크를 통해 입/출력 할 수 있는 스트림

  • Serializable
    -> 직렬화가 될 수 있는 객체가 상속받는 인터페이스
    --> ObjectOutputStream이 객체를 내보낼 때
    해당 인터페이스를 상속받은 객체인 경우만 직렬화 작업 진행

    Serializable을 상속했지만 구현할 메소드 없음 == 마커 인터페이스 (표시 용도 인터페이스)

IOService

package edu.kh.io.model.service;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

import edu.kh.io.dto.Student;

//입력 출력 stream() close() 제대로 알기

public class IOService {

	//IO
	
	//Input  (입력): 외부 -> 내부로 데이터를 들여오는 것
	//Output (출력): 내부 -> 외부로 데이터를 내보내는 것
	
	//Stream: 입/출력 통로 역할(데이터가 흘러가는 통로)
	//		  기본적으로 Stream은 단방향
	
	//1) 파일 출력(내부 == 프로그램 , 외부 == 파일)
	
	public void output1() {
		
		FileOutputStream fos = null;
		// FileNotFoundException 객체 생성 시 
		// FileNotFoundException 예외가 발생할 가능성이 있음 -> 예외 처리 필요
		
		try {
			fos = new FileOutputStream("test1.txt");
			//현재 프로그램에서
			//test1.txt 파일로 출력하는 통로 객체 생성
			
			//파일에 "Hello" 내보내기
			String str = "Hello";
			
			for(int i = 0; i<str.length(); i++) {
				System.out.println(str.charAt(i));
				
				//"Hello"를 한 문자씩 끊어서 파일로 출력하기
				fos.write(str.charAt(i));
				
				//write()는 IOException을 발생시킬 가능성이 있다.
			}
			
		}catch(IOException e) {  //IO~~는 FileNot~~의 부모라서 IO만 작성
			System.out.println("예외 발생");
			e.printStackTrace(); //예외 추적
		}finally {
			//예외 발생 여부와 관계 없이 무조건 수행
			
			//사용한 스트림 자원 반환(통로 없앰) --> 필수 작성!!!!!
			//프로그램 메모리 관리 차원에서 항상 다 쓰면 끊어줌
			// -> 작성 안 할 시 문제점이 될 수 있다.
			
			try {
				fos.close(); //오류 난 거에 surround 누르면 자동완성 해줌
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	//2) 파일 출력(문자 기반 스트림)
	public void output2() {
		
		FileWriter fw = null; //프로그램 -> 파일로 쓰는 문자 기반 스트림
		
		try {
			
			fw = new FileWriter("test2.txt", true); //외부 파일과 연결하는 스트림 객체 생성
			// fw = new FileWriter("경로", 이어쓰기 옵션);
										// -> byte 기반 스트림도 사용 가능한 옵션
			
			
			String str = "안녕하세요. Hello. 20. !#\n";
			
			// fw.write(int c):한 문자씩 출력
			// fw.write(String s): 한 줄씩 출력
			
			
			fw.write(str);
			//실행했는데 출력 안 됨
			// -> 한 줄은 통째로 보내기 위해 "버퍼"이용하는데 아직 버퍼에 담겨 있음
			// --> 강제로 밀어넣어서 버퍼를 비워야 함
			
			//close() 구문을 수행하면 통로에 남아있는 내용을 모두 내보내고 통로 없앰
			
			
		}catch(IOException e) {
			e.printStackTrace(); //예외 추적
		}finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	//3) 파일 입력: 외부(파일) -> 내부(프로그램)으로 읽어오기
	public void input1() {
		
		FileInputStream fis = null; //파일 -> 프로그램으로 읽어오는 바이트 기반 스트림
		
		
		//입출력 할 땐 try catch finally 필수
		try {
			fis = new FileInputStream("test1.txt");
			
			//FileInputStream은 1byte씩만 읽어올 수 있다.
			while(true) {
				
				int data = fis.read();  //다음 1byte를 읽어오는데 정수형임
										// 다음 내용이 없으면 -1 반환
				
				if (data == -1) { //다음 내용 없으면 종료
					break;
				}else { //반복 종료 안 됐으면 char로 강제 형변환하여 문자로 출력
					System.out.print((char)data);
				}
				
			}
			
		}catch(IOException e) {
			e.printStackTrace(); //예외 추적
		}finally {
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}
	
	//4) 파일 입력(문자 기반 스트림)
	public void input2() {
		
		FileReader fr = null;
		
		try {
			
			fr = new FileReader("test1.txt");
			
			while(true) {
				
				int data = fr.read(); //다음 한 문자를 읽어옴, 없으면 -1
				
				if (data == -1) {
					break;
				}else {
					System.out.print((char)data);
				}
			}
			
		} catch (IOException e) {
			e.printStackTrace(); //예외 추적
		}finally {
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	// 5) 객체 출력 보조 스트림
    //object 파일 만들기
	public void objectOutput() { //프로젝트 파일 눌러서 F5 누르면 정상적으로 실행됨
		
		// ObjectXXXStream: 객체를 파일 또는 네트워크를 통해 입/출력 할 수 있는 스트림
		
		// ObjectOutputStream
		// -> 객체를 바이트 기반 스트림으로 출력할 수 있게 하는 스트림
		
		//	  조건: 출력하려는 객체에 직렬화 가능 여부를 나타내는 
		//		   Serializable 인터페이스를 상속받아야 한다.
		
		ObjectOutputStream oos = null;
		
		try {													//경로
			oos = new ObjectOutputStream(new FileOutputStream("object/Student.txt"));
						//보조 스트림 --> 실질적으로 내보낼 수 있는 스트림 필요(FileOutputSream)
			//내보낼 학생 객체 생성
			Student std = new Student("홍길동", 3, 5, 7, '남');
			
			//학생 객체를 파일로 출력
			oos.writeObject(std);
			
			System.out.println("학생 출력 완료");
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
				try {
					if (oos != null) oos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
		
	}
	
	// 6) 객체 입력 보조 스트림
	public void objectInput() {
		
		ObjectInputStream ois = null;
		
		try {
			
			ois = new ObjectInputStream(new FileInputStream("object/Student.txt"));
			
			// Object가 Student 자식 객체를 참조할 수 있기 때문에 다운 캐스팅
			Student std = (Student)ois.readObject(); 
			// readObject() : 직렬화된 객체 데이터를 읽어와서 역직렬화 시켜 
			//				  정상적인 객체 형태로 반환
			// throws IOException, ClassNotFoundException
			
			System.out.println(std);
			
		} catch (Exception e) {
			
		} finally {
			try {
				if(ois != null) ois.close();
			} catch(IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	// 7) List에 Student 객체를 담아서 파일로 출력
	public void listOutput() {
		
		ObjectOutputStream oos = null;
		
		try {
			
			oos = new ObjectOutputStream(new FileOutputStream("object/studentList.ini"));
			
			List<Student> list = new ArrayList<>(); //뒤 <> 빈칸으로 놔둬도 됨 
			
			list.add(new Student("A", 1,1,1, '여'));
			list.add(new Student("B", 2,2,2, '남'));
			list.add(new Student("C", 3,3,3, '여'));
			list.add(new Student("D", 1,2,3, '남'));
			
			
			oos.writeObject(list);
			//writeObject(객체): 출력하려는 객체는 직렬화가 가능해야 한다.
			//					Serializable 인터페이스 구현 필수
			
			//컬렉션은 모두 직렬화가 가능하도록 Serializable 인터페이스 구현 O
			//단, 컬렉션에 저장하는 객체가 직렬화 가능하지 않다면
			//출력되지 않는다. (NotSerializableException 발생)
			
			
			System.out.println("학생 출력 완료");
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			
			try {
				if(oos != null) oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
		
	}
	
	public void listInput() {
		
		ObjectInputStream ois = null;
		
		
		try {

			ois = new ObjectInputStream(new FileInputStream("object/studentList.ini"));

			List<Student> list = (List<Student>) ois.readObject();
			
			

			for( Student std : list) {
				System.out.println(std.getName()); //이름만 얻어오기
			}

		} catch (Exception e) {

		} finally {
			try {
				if (ois != null)
					ois.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}
	
	
}

Student

package edu.kh.io.dto;

import java.io.Serializable;
// Serializable
// -> 직렬화가 될 수 있는 객체가 상속받는 인터페이스
// --> ObjectOutputStream이 객체를 내보낼 때
//	   해당 인터페이스를 상속받은 객체인 경우만 직렬화 작업 진행

// Serializable을 상속했지만 구현할 메소드 없음
// == 마커 인터페이스
//	 (표시 용도 인터페이스)

public class Student implements Serializable{ //직렬화 가능 여부를 나타냄
			//노란 줄 떠서 첫번째 것 클릭
	
	/**
	 * 역직렬화 과정에서 객체가 꼬이는 상황 발생할 수 있음
	 * -> 시리얼 넘버 부여 (굳이 안 해도 됨)
	 */
	private static final long serialVersionUID = 165264658L;
	
	private String name;
	private int grade;
	private int classRoom;
	private int number;
	private char gender;
	
	public Student() {}

	public Student(String name, int grade, int classRoom, int number, char gender) {
		super();
		this.name = name;
		this.grade = grade;
		this.classRoom = classRoom;
		this.number = number;
		this.gender = gender;
	}

	public String getName() {
		return name;
	}

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

	public int getGrade() {
		return grade;
	}

	public void setGrade(int grade) {
		this.grade = grade;
	}

	public int getClassRoom() {
		return classRoom;
	}

	public void setClassRoom(int classRoom) {
		this.classRoom = classRoom;
	}

	public int getNumber() {
		return number;
	}

	public void setNumber(int number) {
		this.number = number;
	}

	public char getGender() {
		return gender;
	}

	public void setGender(char gender) {
		this.gender = gender;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", grade=" + grade + ", classRoom=" + classRoom + ", number=" + number
				+ ", gender=" + gender + "]";
	}
	

}

IORun

package edu.kh.io.run;

import edu.kh.io.model.service.IOService;

public class IORun {

	public static void main(String[] args) {

		IOService service = new IOService();
		
//		service.output1();
		service.output2();
//		service.input1();
//		service.input2();
//		service.objectOutput();
//		service.objectInput();
		service.listOutput();
//		service.listInput();
		
		
		
		
		
	}

}
profile
개발 일지

0개의 댓글