본문 바로가기

자바

day21

자바 파일과 i/o[input / output]  -  두 대상 간의 데이터를 주고 받는것 

자바 입출력 스트림의 종류 
데이터 기본 단위 : 바이트 스트림 
-바이트 스트림은 1바이트를 입/출력 할 수 있는 스트림 
-파일의 복사

문자 스트림 
-유니코드로 된 문자를 입/출력 하는 스트림 
-2바이트를 입/출력 - 세계 모든 언어로 구성된 파일을 입/출력 하기에 적합 
-이미지,동영상과 같은 바이너리 데이터는 입/출력 할 수 없음
-문자 데이터만 입/출력 가능  

프로그램에서 성능 => 속도 

버퍼 스트림[보조, 필터 스트림]
-단독 사용 불가 
-스트림의 기능을 향상 시키거나 새로운 기능을 추가하기 위해 사용
-문자 입력 스트림으로부터 문자를 읽어 들이거나 문자 출력 스트림으로 문자를 내보낼 때 버퍼링을 함으로써 문자,문자 배열, 문자열 라인 등을 보다 효율적으로 처리 

*****참고*****
FileInputStream
FileOutputStream 

해당 객체로 일괄 처리 / 객체 직렬화 :
ObjectInputStream - 읽기 -> 복원 (클래스의 메소드 :인스턴스복원)
ObjectOutputStream - 쓰기 -> 저장 (클래스의 메소드 :인스턴스저장)


파일에 있는 데이터를 읽어 들이는 것을 input
파일에 있는 데이터를 내보내는 것을 output

stream [스트림] - 흐름 , 물줄기
-연속적인 데이터의 흐름
-데이터를 운반[입출력]하는데 사용되는 연결통로
-하나의 스트림으로 입출력을 동시에 수행할 수 없다.(단방향 통신) 
-읽기,쓰기가 동시에 되지 않음
-읽는 스트림과 쓰는 스트림을 하나씩 열어[instance 생성] 사용해야 함
-FiFo 구조[ first in first out] - 먼저 들어간 것이 먼저 나오는 형태 -> 데이터의 순서가 바뀌지 않음 
-스트림은 지연될 수 있음 


 
inputStream의 개념 
출력 :- file로 쓰는 것 [ 하드디스크에 저장되어 있는 파일]
        - usb와 같은 외부 메모리 장치
        - 네트워크로 연결되어 있는 컴퓨터
     - 사운드 카드, 오디오카드 같은 멀티 미디어 장치 
입출력 대상이 달라지면 프로그램 상에서의 입출력 방식도 달라지는 것이 보통이다.
하지만 자바에서는 입출력대상에 상관없이 입출력의 진행 방식이 동일 하도록 별도의 'i/o모델'을 정의하고 있다. 

InputStream class 
InputStream in = new FileInputStream("run.exe);
int bData = in.read(); / 1byte 데이터
in.close();
-대표적인 메소드 : read() - 더 이상 읽어들일 데이터가 없다면 '-1'을 반환 , close() - 입력 스트림 소멸  

OutputStream class
write(), cloes() 
OutputStream out = new FileOutputStream("home.bin);
out.write(1); / 4바이트 int형 정수 1의 하위 1바이트만 전달된다.
ouut.close(); 

bufferedReader 와 bufferedWriter 
-text기반 파일은 buffered 이용 
-입출력 효율을 높이기 위해 버퍼(char[])를 사용하는 보조스트림 
-라인 단위의 입출력이 편리하다. 

I/O 파일 입출력 관련 예제
package ex.io1;

import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;

public class MemoUtil {
	File[] list;
private	File utilMemo;

	//현재 시간을 저장하는 메서드
	public static String nowDateTime() {		
		LocalDateTime current = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yy년 MM월 dd일 hh시 mm분");
		String now = current.format(formatter);
		return now;
	}
	// String 타입으로 리턴해주는 스캐너 메서드
	public static String getUserInput() {
		Scanner scan = new Scanner(System.in);
		String input = scan.nextLine();
		return input;
	}
	//저장된 파일의 목록을 보여주는 메서드 
	public void listFile() {
		System.out.println("찾을 경로의 폴더를 입력해주세요.");
		String rootFolder = getUserInput();
		utilMemo = new File(rootFolder);
		if(utilMemo.exists()) {
		list = utilMemo.listFiles();
		for(int i = 0; i < list.length; i++) {
			System.out.println(list[i].getName());
			}
		}else {
			System.out.println("잘못된 경로입니다 다시 입력하세요.");
		}
	}
	//저장된 파일을 찾는 메서드 
	public void findFile() {
		System.out.println("찾을 경로의 폴더를 입력해주세요");
		String findFolder = getUserInput();
		utilMemo =	new File(findFolder);
		if(utilMemo.exists()) {
		System.out.println("찾을 파일의 제목을 입력해주세요.");
		String memoFile = getUserInput();
			
			try {
				BufferedReader in = new BufferedReader(new FileReader(utilMemo+"\\"+memoFile+".txt"));
				String str;
				while(true) {
					str = in.readLine();
					if(str == null) {
						break;
					}
					System.out.println(str);
				}
				in.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}else {
			System.out.println(findFolder+"의 폴더가 존재하지 않습니다.");
		}
	}
	
	public void writeFile() {
//		1.콘솔기반으로 메모장 기능을 만들어 봅시다.
		//제목,내용,날짜 		
		System.out.println("파일에 메모할 내용을 입력해주세요.");
		System.out.print("제목을 입력하세요: >> ");
		String title = getUserInput();
		System.out.print("작성자를 입력하세요. : >>");
		String name = getUserInput();
		System.out.print("내용을 입력하세요.: >>");
		String content = getUserInput();
		System.out.println("날짜와 시간은 현재시간으로 저장됩니다.");
		String nowT = nowDateTime();
//		①File 클래스를 이용해서 저장 폴더 생성
		//경로 생성 
		System.out.println("저장할 경로와 폴더명을 입력해주세요.");
		String newDir = getUserInput();
		File memoF = new File(newDir);
		if(!memoF.exists()) {
			//경로의 폴더를 만들어 주는 메서드 
			memoF.mkdirs();
			System.out.println("메모장 폴더를 생성합니다.");
		}
//		②문자기반 스트림을 이용해서 날짜와 제목, 메모를 파일에 저장
		//스캐너로 입력받은 문자열을 write메소드에 인자로 전달
		try {
			
		//	③파일의 이름은 날짜와 메모의 제목을 이용해서 생성			
			BufferedWriter bWrite = new BufferedWriter(new FileWriter(newDir+"\\"+title+".txt"));
			bWrite.write("제목 :"+title);
			bWrite.newLine();
			bWrite.write("작성자 :"+name);
			bWrite.newLine();
			bWrite.write("내용 :"+ content);
			bWrite.newLine();
			bWrite.write("작성 시간 :"+nowT);			
			bWrite.close();
			System.out.println("작성을 완료하였습니다.");
		
	}	catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	}
}
===========================================================================================================
package ex.io1;

import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;

public class MemoTest {	
	
	public static void main(String[] args) {
		//저장된 파일의 내용을 출력해주는 기능의 인스턴스 생성
		MemoUtil memoUtil = new MemoUtil();
		
		int num = Integer.parseInt(MemoUtil.getUserInput());
		while(!(num == 4)) {
			showMenu();
			switch(num) {
			case 1:
				System.out.println("1.메모장 작성");
	//		    메모장 기능을 구현하고 경로 폴더를 지정하고 쓰는 메서드 
				memoUtil.writeFile();
				break;
			case 2: 
				System.out.println("2.메모장 파일 읽기");
	//		    파일 읽기 기능을 구현해봅시다.
				memoUtil.findFile();
				break;
			case 3:
				System.out.println("3.메모리스트 출력");
	//			메모리스트를 보여줍니다.
				memoUtil.listFile();
				break;
			case 4: 
				System.out.println("프로그램이 종료됩니다.");
				System.exit(0);
				break;
			}
	
		}
	}
	public static void showMenu(){
		System.out.println("=============================");
		System.out.println("=============메뉴=============");
		System.out.println("1.메모장 작성");
		System.out.println("2.메모장 파일 읽기");
		System.out.println("3.메모장 리스트 출력");
		System.out.println("4.프로그램 종료");
		System.out.println("=============================");
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

직렬화(serialization) :
-인스턴스가 파일에 저장되는 과정(저장을 위해 거치는 과정)을 가리켜 '직렬화' 라고 한다.
-객체를 '연속적인 데이터'로 변환하는 것. 반대과정은 '역직렬화' 라고 한다,
-객체의 인스턴스변수들의 값을 일렬로 나열하는 것 
직렬화의 대상이 되는 인스턴스의 클래스는 java.io.serializable 인터페이스를 구현해야 한다

직렬화의 대상에서 제외 - transient .

실제 프로그램 개발에서는 절대 경로가 아닌 상대경로를 이용하는 것이 일반적이다. 그래야 실행 환경 및 실행위치의 변경에 따른 문제점을 최소화 할 수 있기 때문이다. 

직렬화 예제
=======================================================================================
		직렬화를 위한 클래스 생성 
package ex1.io3;

import java.io.Serializable;
import java.util.*;

import com.test_14.FootballPlayer;

public class Player implements Serializable,Comparable<Player>{
	String name;
	int number;
	String team;
	int age;
	public Player(String name, int number, String team, int age) {
		this.name = name;
		this.number = number;
		this.team = team;
		this.age = age;
	}
	
	public void showData() {
		System.out.println("이름:"+name);
		System.out.println("번호:"+number);
		System.out.println("팀:"+team);
		System.out.println("나이:"+age);
	}
	public int hashCode() {
		return age % 3;
	}

	@Override
	public int compareTo(Player o) {
		int result = this.team.compareTo(o.team);
		//같은 팀이라면 
		if(result == 0) {
		
			result = this.name.compareTo(o.name);
			//이름이 같다면 
			if(result == 0) {
				// 나이로 비교해서 정렬
				
				result = this.age - o.age;
			}
		}
		
		return result;
	}
	public boolean equals(Object obj) {
		boolean result = false;
		if (obj != null && obj instanceof Player) {
			Player fb = (Player) obj;
			if (this.team.equals(fb.team) && this.name.equals(fb.name)) {
				result = true;
			}
		}
		return result;
	}
	
	public String toString() {
		return team+ name +age +number;
	}
}

===================================================================================== 
package ex1.io3;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class PlayerList {

	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		// file의 경로지정 
		File playerInfo = new File("C:\\myTextEx\\player");
		
		if(!playerInfo.exists()) {
			playerInfo.mkdirs();
			System.out.println("player 폴더를 생성하였습니다!");
		}
		// 인스턴스 저장
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(playerInfo+"\\Player.ser"));
		List<Player> player = new ArrayList<>();
		player.add(new Player("son",7,"tot",28));
		player.add(new Player("park",7,"mu",38));
		player.add(new Player("cha",1,"ger",33));
		player.add(new Player("ji",5,"ch",22));
		player.add(new Player("son",10,"tot",27));
				
		out.writeObject(player);
		out.close();
		System.out.println("저장을 완료하였습니다.");
		
		// 인스턴스 복원
		ObjectInputStream in = new ObjectInputStream(new FileInputStream(playerInfo+"\\Player.ser"));
			ArrayList<Player> rePlayer =(ArrayList<Player>) in.readObject();
			in.close();
			System.out.println("인스턴스 복원 완료!");
			//인스턴스 출력 
			System.out.println("인스턴스 출력");
						
			Iterator itr = rePlayer.iterator();
			while(itr.hasNext()) {
		System.out.println(itr.next());
			}
	}
}

'자바' 카테고리의 다른 글

day23  (0) 2021.06.13
day22  (0) 2021.06.13
Day20  (0) 2021.06.01
Day19  (0) 2021.05.31
Day18  (0) 2021.05.28