입출력 클래스

woom·2022년 11월 23일
0

JAVA

목록 보기
17/18
post-thumbnail

🌼 입출력 클래스

  • 입력 클래스에서 인풋 스트림을 통해 전달받은 값을 리드 메소드로 읽어서 변수에 값 저장

  • 하나의 클래스가 하나의 스트림을 뜻하지 않음

  • 기본 스트림(read, write)에서 보조 스트림(더 많은 메소드)으로 확장 가능

  • 파일 처리 (파일 클래스) : 메모리에 저장하면 사용후 값이 소멸되므로 반 영구적으로 사용하기 위해 파일에 값을 넣어 저장

    • 파일 처리 위해 FileInputstream, FileOutputstream 사용


📌 java.io 패키지

  • 입력과 출력 관련 클래스가 선언된 패키지
  • EOF (End Of File) : 입력종료로 [Ctrl+Z] 신호를 입력하면 프로그램 종료 (입력값==-1)
    • [Ctrl+C] : 실행 취소
    • 도스쉘에서 실행해야 하는데 이클립스 실행으로 하면 실행이 안될 가능성 존재
  • 스트림(Stream) : 값을 전달하기 위한 목적으로 생성된 입력클래스 또는 출력클래스의 객체
    • java.io 패키지에 속해 있는 클래스를 이용해서 객체 생성
    • 시냇물이 흐르는 모양을 모델링하여 만들어 값이 한쪽 방향으로만 전달되며 순차적으로 처리

📙 원시데이터 기반 스트림

  • 원시데이터 기반 스트림(Byte Stream) : 가공되지 않은 원시데이터를 전달하기 위한 입출력 스트림 (일반적인 데이터 처리)
    • 값을 1Byte 단위로 입력 또는 출력하기 위한 스트림
    • InputStream, OutputStream 클래스(추상클래스이므로 상속받아 사용)를 최상위 클래스로 하는 자식클래스를 이용하여 생성
    • ex) 파일 전송을 위해서는 바이트 스트림 사용
  • System.in : Java 프로그램 개발을 위해 기본적으로 제공되는 키보드 입력스트림 (입력 통로만 만들어 준것)

    • InputStream 클래스를 기반으로 제공되는 입력스트림(객체)
    • 키보드를 누르면 이벤트가 발생된 키보드의 값을 입력스트림으로 전달
  • InputStream.read() : 입력스트림에 존재하는 값(1Byte)을 읽어 [4byte(中3byte는 쓸데없는 값)로:]반환하는 메소드

    • 입력스트림에 값이 없는 경우 스레드는 일시 중지 상태로 전환
    • 입력스트림에 엔터(Enter)가 입력될 경우 스레드 다시 실행
  • System.out : Java 프로그램 개발을 위해 기본적으로 제공되는 모니터 출력스트림

    • OutputStream 클래스(PrintStream 클래스: Outputstream의 자식 클래스)를 기반으로 제공되는 출력스트림(객체)
    • OutputStream의 메소드인 write도 가능하고 PrintStream 메소드인 println 사용도 가능
    • 출력스트림에 값을 전달하면 모니터에 출력
  • OutputStream.write(int b) : 출력스트림에게 값(1Byte)을 전달하는 메소드


🐣 예제 (원시데이터)

  • 키보드로 원시데이터를 입력받아 모니터에 전달하여 출력하는 프로그램
public class ByteStreamApp {
	public static void main(String[] args) throws IOException {
		System.out.println("키보드를 눌러 값을 입력하세요.[종료 : Ctrl+Z]");
		
		int readByte;//키보드 입력값을 저장하기 위한 변수, int 4byte中 1byte 사용
		
		while(true) {
			//입력스트림 또는 출력스트림 관련 메소드는 IOException 발생
			//일반 예외이므로 예외처리 하지 않을 경우 에러 발생(JVM의 메인메소드로 전달)
			readByte=System.in.read();
			
			//입력종료신호(Ctrl+Z : EOF)가 전달된 경우 반복문 종료
			if(readByte==-1) break;
			
			System.out.write(readByte);}
		
		System.out.println("[메세지]프로그램을 종료합니다."); }}
   




📙 문자데이터 기반 스트림

  • 문자데이타 기반 스트림(Character Stream) : 원시데이타를 가공처리한 문자데이타를 전달하기 위한 입출력 스트림

    • 원시데이타를 가공 처리하여 문자데이터로 변환 : 인코딩
    • 인코딩한 문자형태 : 캐릭터셋(CharSet) ex. 한글 조합형 utf-8
    • 값을 2Byte 단위로 입력 또는 출력하기 위한 스트림
    • Reader 클래스와 Writer 클래스를 최상위 클래스로 하는 자식클래스를 이용하여 생성
  • InputStreamReader : InputStream 객체를 전달받아 문자데이타를 입력받기 위한 스트림(Reader 객체)을 생성하기 위한 클래스

  • OutputStreamWriter : OutputStream 객체를 전달받아 문자데이타를 전달하기 위한 스트림(Writer 객체)을 생성하기 위한 클래스

  • PrintWriter : OutputStream 객체를 전달받아 문자데이타를 전달하기 위한 스트림(Writer 객체)을 생성하기 위한 클래스

    • OutputStreamWriter 클래스보다 많은 메소드를 제공하는 클래스
  • Reader.read() : 입력스트림에 존재하는 값(2Byte)을 읽어 반환하는 메소드

  • Writer.write() : 출력스트림에게 값(2Byte)을 전달하는 메소드

    • 문자데이터는 출력버퍼(임시메모리)에 일정 크기만큼 저장하고 한번에 출력스트림으로 전송하여 처리
    • Writer.flush() : 출력버퍼에 저장된 문자데이타를 출력스트림으로 모두 전달하는 메소드

🐣 예제 (문자데이터)

  • 키보드로 문자데이타를 입력받아 모니터에 전달하여 출력하는 프로그램
public class CharacterStreamApp {
	public static void main(String[] args) throws IOException {
		System.out.println("키보드를 눌러 값을 입력하세요.[종료 : Ctrl+Z]");

		InputStreamReader in=new InputStreamReader(System.in);//Reader 객체생성

		//OutputStreamWriter out=new OutputStreamWriter(System.out);
        //OutputStreamWriter로 확장하는 이유 : 2바이트로 읽었으면
		// 2바이트로 출력필요. 1바이트로 출력하면 값이 깨져 데이터 손실 발생 
		PrintWriter out=new PrintWriter(System.out);//Writer 객체생성
		
		int readByte;//키보드 입력값을 저장하기 위한 변수
		
		while(true) {
			readByte=in.read();	//입력값 read
			
			if(readByte==-1) break;
			
			out.write(readByte);//입력값 전달
			
			out.flush();}//입력값 전부 전달
		
		System.out.println("[메세지]프로그램을 종료합니다."); }}





📙 보조스트림 (확장)

  • Java에서 기본적으로 제공되는 키보드 입력스트림(System.in)을 InputStreamReader 객체의 입력스트림으로 확장하여 (인코딩 처리된) 문자데이터를 입력받을 수 있도록 설정하고 BufferedReader (보조스트림 : 확장하여 더 많은 메소드 사용할 수 있도록 해줌) 객체의 입력스트림으로 확장하여 대량의 문자데이타를 입력 받을 수 있도록 설정

    • 입출력 관련 보조 클래스로 스트림의 다단계 연결을 이용하여 스트림 확장 가능
    • 키보드로 문자열을 입력받기 위한 기능을 제공받기 위한 입력스트림 생성
    • 형식) BufferedReader 입력변수 = new BufferedReader(new InputStreamReader(System.in));
    • ex) 2바이트로 읽었으면 2바이트로 출력해야해 1바이트로 출력하면 데이터 손실 발생
    • BufferedReader.readLine() : 입력스트림에서 문자열을 얻어와 반환하는 메소드

🐣 예제 (보조스트림)

  • 키보드로 이름과 태어난 년도를 입력받아 이름과 나이를 계산하여 출력하는 프로그램
public class ConsoleIOApp {
	public static void main(String[] args) throws IOException {
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		
		//Java에서 제공되는 모니터 출력스트림(System.out)은 PrintStream 객체로 
		//생성되어 print() 또는 println() 메소드로 값을 문자열로 변환하여 출력
		System.out.print("이름 입력 >> ");

		String name=in.readLine();
		
		System.out.print("태어난 년도 입력 >> ");
		//입력받은 문자열을 정수값으로 변환하여 저장(NumberFormatException 발생 가능)
		int birthYear=Integer.parseInt(in.readLine());
		
		int age=Calendar.getInstance().get(Calendar.YEAR)-birthYear+1;
		
		System.out.println("[결과]"+name+"님의 나이는 "+age+"살입니다."); }}





🌼 File 클래스

  • 파일(디렉토리 - 폴더) 관련 정보를 저장하기 위한 클래스

  • File : 값을 반 영구적으로 저장할 수 있는 물리적인 저장 단위, 파일을 그룹화 시킨것 폴더(디렉토리)


📌 파일경로 표현 방법

  • 파일경로 : 시스템이 존재하는 파일 위치를 표현하는 방법
    • Windows 운영체제에서는 폴더(드라이브)와 파일을 구분하기 위해 \ 기호 사용
    • Java에서는 \ 기호가 회피문자(Escape Character)를 표현하는 용도로 사용
    • \ 기호를 문자로 사용하기 위해 \ 형태의 회피문자(Escape Character)를 표현
    • Windows 운영체제를 제외한 나머지 운영체제에서는 폴더(드라이브)와 파일을 구분하기위해 / 기호 사용
    • Java에서는 파일 경로를 표현하기 위해 \ 기호 대신 / 기호 사용 가능
    1. 절대경로 표현방법 : 파일경로를 최상위 디렉토리를 기준으로 파일 위치를 표현하는 방법
    • ex) File 변수 =new File("c:/data/xyz.txt");
    1. 상대경로 표현방법 : 현재 실행 프로그램의 작업디렉토리(workspace)를 기준으로 파일 위치를 표현하는 방법
    • 이클립스에서는 프로젝트 폴더(ex. src)를 작업 디렉토리로 처리
    • 파일경로를 상대경로 표현방법으로 전달하여 File 객체 생성
    • ex) File 변수 =new File("src");
    • 현재 프로그램의 작업디렉토리는 프로젝트 폴더로 설정
    • 상대경로 표현방법은 [..] 기호를 사용하여 상위 디렉토리(폴더)를 표현하며 [파일] 형식으로 폴더에 존재하는 파일 또는 하위 디렉토리(폴더) 표현
    • ex) 현재 디렉토리 안에 있는 src 표현 : ./src
      현재 작업하고 있는 상위 디렉토리 아래에 있는 : .. /java_2

📌 파일 관련 메소드

  • File(String pathname) : 시스템(운영체제 - OS)의 파일경로를 전달받아 File 객체를 생성하는 생성자

  • File.exists() : File 객체에 저장된 파일경로에 파일(디렉토리)이 없는 경우 [false]를 반환, 파일이 있는 경우 [true]를 반환하는 메소드

  • File.mkdir() : File 객체에 저장된 파일경로를 이용하여 디렉토리를 생성하는 메소드

  • File.createNewFile() : File 객체에 저장된 파일경로를 이용하여 파일를 생성하는 메소드

    • IOException 발생되므로 예외처리해야만 에러 미발생
  • File(String parent, String child) : 시스템(운영체제 - OS)의 파일경로를 부모(디렉토리)와 자식(파일)으로 구분하여
    전달받아 File 객체를 생성하는 생성자

  • File.delete() : File 객체에 저장된 파일경로의 파일을 삭제하는 메소드

  • File.toString() : File 객체에 저장된 파일경로를 문자열로 반환하는 메소드

  • File.getAbsolutePath() : File 객체에 저장된 파일경로를 절대경로의 문자열로 반환하는 메소드

  • File.isDirectory() : File 객체에 저장된 파일경로가 디렉토리인 경우 [true]를 반환하는 메소드

  • File.listFiles() : File 객체에 저장된 파일경로의 자식 파일 목록을 File 객체 배열로 반환하는 메소드

  • File.isFile() : File 객체에 저장된 파일경로가 파일인 경우 [true]를 반환하는 메소드


🐣 예제 (파일)

public class FileApp {
	public static void main(String[] args) throws IOException {
		File fileOne=new File("c:\\data");

		if(fileOne.exists()) {
			System.out.println("c:\\data 폴더가 이미 존재합니다.");
		} else {
			fileOne.mkdir();
			System.out.println("c:\\data 폴더를 생성 하였습니다.");
		}//c:\\data 폴더가 이미 존재합니다
		

		//File fileTwo=new File("c:\\data\\xyz.txt");
		File fileTwo=new File("c:/data/xyz.txt");	
        // Java에서는 파일 경로를 표현하기 \ 기호 대신 / 기호 사용 가능

		if(fileTwo.exists()) {
			System.out.println("c:\\data\\xyz.txt 파일이 이미 존재합니다.");
		} else {
			fileTwo.createNewFile();
			System.out.println("c:\\data\\xyz.txt 파일을 생성 하였습니다.");
		}//c:\data\xyz.txt 파일을 생성 하였습니다.
		

		//File fileThree=new File("c:/data/xyz.txt");
		File fileThree=new File("c:/data","xyz.txt");
		
		if(fileThree.exists()) {
			fileThree.delete();
			System.out.println("c:\\data\\xyz.txt 파일을 삭제 하였습니다.");
		} else {
			System.out.println("c:\\data\\xyz.txt 파일이 존재하지 않습니다.");
		}//c:\data\xyz.txt 파일을 삭제 하였습니다.
		

		//파일경로를 상대경로 표현방법으로 전달하여 File 객체 생성
		// → 상대경로 표현방법은 [..] 기호를 사용하여 상위 디렉토리(폴더)를 표현하며 
		//[파일] 형식으로 폴더에 존재하는 파일 또는 하위 디렉토리(폴더) 표현 
		File fileFour=new File("src");
		
		if(fileFour.exists()) {
			//System.out.println("파일 경로 = "+fileFour.toString());
			System.out.println("파일 경로 = "+fileFour);//파일 경로 = src
			//File.getAbsolutePath():File객체에 저장된 파일경로를 절대경로의 문자열로 반환
			System.out.println("파일 경로 = "+fileFour.getAbsolutePath());
		} else {
			System.out.println("작업디렉토리에 src 폴더가 없습니다.");
		}//파일 경로 = C:\Users\ITWILL\eclipse-workspace\java-3\src
		

		File fileFive=new File("c:/");

		//File.isDirectory():File 객체에 저장된 파일경로가 디렉토리인 경우 [true]를 반환
		if(fileFive.isDirectory()) {
			//File.listFiles():File 객체에 저장된 파일경로의 자식 파일 목록을 배열로 반환
			File[] subFiles=fileFive.listFiles();
			
			System.out.println(fileFive+" 폴더의 자식 목록 >>");
			for(File file:subFiles) {
				if(file.isFile()) {
					System.out.println("파일 = "+file);
				} else {
					System.out.println("폴더 = "+file);
				}//c:\ 폴더의 자식 목록 >> 폴더 = c:\$Recycle.Bin ··· 
 			}
		} }}





🌻 File 입출력

📒 원시데이터 기반 출력스트림

  • FileOutputStream : 파일에 원시데이터를 전달하기 위한 출력스트림을 생성하는 클래스

  • FileOutputStream(String name) : 파일경로를 전달받아 파일 출력스트림을 생성하는 생성자

    • 전달받은 파일경로에 파일이 없는 경우 FileNotFoundException 발생 : 예외처리
    • 예외처리 하지 않고 예외를 전달한 경우 파일을 자동으로 생성하여 출력스트림 반환
    • 전달받은 파일경로에 파일이 있는 경우 기존 파일값 대신 새로운 값이 파일에 저장 (덮어씌우기)
    • ex) FileOutputStream 변수 = new FileOutputStream("c:/data/byte.txt");
  • FileOutputStream(String name, boolean) : 파일경로와 추가 유무에 대한 논리값을 전달받아 파일 출력스트림을 생성하는 생성자
    • false : 파일 덮어씌우기(기본), true : 파일 이어쓰기
  • FileOutputStream .close() : 파일 출력스트림을 제거하는 메소드
    • 파일에는 입력스트림 또는 출력스트림을 1개씩만 생성 가능 (파일은 다중처리 불가능)
    • 파일 처리를 위한 입력스트림 또는 출력스트림은 사용 후 반드시 제거

🐣 예제

  • 키보드 입력값을 원시데이타로 제공받아 파일에 전달하여 저장하는 프로그램
public class FileByteSaveApp {
	public static void main(String[] args) throws IOException {
		System.out.println("키보드를 눌러 값을 입력하세요.[종료 : Ctrl+Z]");

		FileOutputStream out=new FileOutputStream("c:/data/byte.txt",true);
        //출력스트림 생성하여 이어쓰기
		
		int readByte;//키보드 입력값을 전달하기 위한 변수
		
		while(true) {
			readByte=System.in.read();//키보드 입력스트림에서 원시데이타를 반환받아 저장
			if(readByte==-1) break;	//프로그램 종료
			out.write(readByte);//파일 출력스트림으로 원시데이타를 전달하여 저장(SAVE)
		}
		out.close();
		System.out.println("c:\\data\\byte.txt 파일에 입력값이 저장 되었습니다."); }}





📒 원시데이터 기반 입력스트림

  • FileInputStream : 파일에 저장된 값을 원시데이터로 읽기 위한 입력스트림을 생성하는 클래스

  • FileInputStream(String name) : 파일경로를 전달받아 파일 입력스트림을 생성하는 생성자

    • 전달받은 파일경로에 파일이 없는 경우 FileNotFoundException 발생 : 예외처리
    • 파일이 없는 경우 파일 입력스트림을 반환하지 못하므로 반드시 예외처리 (try, catch문 사용)
  • FileInputStream.close() : 파일 입력스트림을 제거하는 메소드

    • 예외 발생과 상관없이 무조건 제거를 위해 try 블럭이 아닌 finally 블럭에서 처리

🐣 예제

  • 파일에 저장된 값을 원시데이타를 읽어와 모니터에 전달하여 출력하는 프로그램
public class FileByteLoadApp {
	public static void main(String[] args) throws IOException {
	FileInputStream in=null;
		try {
			in=new FileInputStream("c:/data/byte.txt");
			
			System.out.println("c:\\data\\byte.txt 파일에 저장된 내용입니다.");
			int readByte;
			while(true) {
				//파일 입력스트림을 이용하여 파일값을 원시데이타로 반환받아 저장 (LOAD)
				readByte=in.read();

				//파일의 마지막에는 무조건 EOF 존재
				if(readByte==-1) break;//파일의 모든 값을 얻어온 경우 반복문 종료
				
				//모니터 출력스트림에 원시데이타를 전달하여 출력
				//print로 출력하면 원시데이터는 숫자로 출력
				System.out.write(readByte);
			}
		} catch (FileNotFoundException e) {
			System.out.println("[에러]대상 파일을 찾을 수 없습니다.");
		} finally {
			//if 구문 사용하여 참조변수에 NULL이 저장되어 있지 않을 경우에만 메소드 호출
			// → NullPointerException 발생 방지
			if(in!=null) in.close(); }}}





📗 문자데이터 기반 출력스트림

  • FileWriter : 파일에 문자데이타를 전달하기 위한 출력스트림을 생성하는 클래스

  • FileWriter(String filename) : 파일경로를 전달받아 파일 출력스트림을 생성하는 생성자

    • 전달받은 파일경로에 파일이 없는 경우 FileNotFoundException 발생 (예외처리)
    • 예외처리 하지 않고 예외를 전달할 경우 파일을 자동으로 생성하여 출력스트림 제공
    • 전달받은 파일경로에 파일이 있는 경우 기존 파일값 대신 새로운 값이 파일에 저장 (덮어씌우기)
    • 형식) FileWriter 변수 = new FileWriter("c:/data/char.txt");
  • FileWriter(String filename, boolean append) : 파일경로와 추가 유무에 대한 논리값을 전달받아 파일 출력스트림을 생성하는 생성자

    • false : 파일 덮어씌우기(기본), true : 파일 이어쓰기
  • FileWriter.close() : 파일 출력스트림을 제거하는 메소드


🐣 예제

  • 키보드 입력값을 문자데이타로 제공받아 파일에 전달하여 저장하는 프로그램
public class FileCharSaveApp {
	public static void main(String[] args) throws IOException {
		System.out.println("키보드를 눌러 값을 입력해 주세요.[종료 : Ctrl+Z]");
		
		InputStreamReader in=new InputStreamReader(System.in);
		FileWriter out=new FileWriter("c:/data/char.txt",true);
		
		int readByte;
		while(true) {
			readByte=in.read();	//키보드 입력값을 문자데이타로 얻어와 저장
			if(readByte==-1) break;
			//문자데이타를 파일 출력스트림을 이용하여 전달하여 저장 (SAVE)
			out.write(readByte);
		}
		out.close();
		System.out.println("c:\\data\\char.txt 파일에 키보드 입력값 저장"); }}
     




📗 문자데이터 기반 입력스트림

  • FileReader : 파일에 저장된 값을 문자데이타로 읽기 위한 입력스트림을 생성하는 클래스

  • FileReader(String filename) : 파일경로를 전달받아 파일 입력스트림을 생성하는 생성자

    • 전달받은 파일경로에 파일이 없는 경우 FileNotFoundException 발생 (예외처리)
    • 파일이 없는 경우 파일 입력스트림을 생성하지 못하므로 반드시 예외처리
  • FileReader.close() : 파일 입력스트림을 제거하는 메소드


🐣 예제

  • 파일에 저장된 값을 문자데이타로 읽어와 모니터에 전달하여 출력하는 프로그램
public class FileCharLoadApp {
	public static void main(String[] args) throws IOException {
		FileReader in=null;
		try {
			in=new FileReader("c:/data/char.txt");
			
			//문자데이타를 전달하기 위한 모니터 출력스트림으로 확장  
			OutputStreamWriter out=new OutputStreamWriter(System.out);
			
			System.out.println("c:\\data\\char.txt 파일에 저장된 내용입니다.");
			int readByte;
			while(true) {
				//파일 입력스트림을 이용하여 파일값을 문자데이타로 반환받아 저장 (LOAD)
				readByte=in.read();

				if(readByte==-1) break;//파일의 모든 값을 얻어온 경우 반복문 종료
				
				//모니터 출력스트림에 문자데이타를 전달하여 출력
				out.write(readByte);
				out.flush();
			}
		} catch (FileNotFoundException e) {
			System.out.println("[에러]대상 파일을 찾을 수 없습니다.");
		} finally {
			//FileReader.close() : 파일 입력스트림을 제거하는 메소드
			if(in!=null) in.close(); }}}





🌼 보조스트림 클래스

  • 스트림을 전달받아 기능을 확장하기 위한 클래스
  • 1-1. BufferedInputStream, 1-2. BufferedOutputStream
  • 2-1. DataInputStream, 2-2. DataOutputStream,
  • 3-1. ObjectOutputStream, 3-2. ObjectInputStream

📘 Buffered 입출력 클래스(파일복사)

  • BufferedInputStream : InputStream 객체를 전달받아 대량의 원시데이타를 읽기 위한 입력스트림을 생성하는 클래스

  • BufferedOutputStream : OutputStream 객체를 전달받아 대량의 원시데이타를 전달하기 위한 출력스트림을 생성하는 클래스

  • BufferedReader : Reader 객체를 전달받아 대량의 문자데이타를 읽기 위한 입력스트림을 생성하기 위한 클래스

  • BufferedWriter : Writer 객체를 전달받아 대량의 문자데이타를 전달하기 위한 출력스트림을 생성하기 위한 클래스


🐣 예제(원시데이터)

  • 원본파일에 저장된 값을 원시데이타로 읽어와 타겟파일에 전달하여 저장하는 프로그램
public class FileCopyByteApp {
	public static void main(String[] args) throws IOException {
		BufferedInputStream in=null;
		BufferedOutputStream out=null;
		try {
			in=new BufferedInputStream(new FileInputStream("c:/data/ban.exe"));
			out=new BufferedOutputStream(new FileOutputStream("c:/data/ban_copy.exe"));

			int readByte;
			while(true) {
				readByte=in.read();
				if(readByte==-1) break;
				out.write(readByte);
			}
			System.out.println("[메세지]파일을 성공적으로 복사 하였습니다.");
		} catch (FileNotFoundException e) {
			System.out.println("[에러]원본파일을 찾을 수 없습니다.");
		} finally {
			in.close();
			out.close(); }}}





🐣 예제(문자데이터)

  • 파일에 저장된 값을 문자데이터로 읽어 타겟파일에 저장시 문제점

    • 텍스트 형식의 원본파일만을 복사하여 타겟파일로 전달하여 저장 가능
    • 텍스트 형식의 파일을 제외한 원본파일(이진파일 - Binary File)은 값에 대한 가공이 발생되어 타겟파일이 변형되어 저장
  • 원본파일에 저장된 값을 문자데이타로 읽어와 타겟파일에 전달하여 저장하는 프로그램

public class FileCopyCharApp {
	public static void main(String[] args) throws IOException {
		BufferedReader in=null;
		BufferedWriter out=null;
		try {
			in=new BufferedReader(new FileReader("c:/data/ban.exe"));
			out=new BufferedWriter(new FileWriter("c:/data/ban_char.exe"));
			
			int readByte;
			while(true) {
				readByte=in.read();
				if(readByte==-1) break;
				out.write(readByte);
			}
			System.out.println("[메세지]파일을 성공적으로 복사 하였습니다.");
		} catch (FileNotFoundException e) {
			System.out.println("[에러]원본파일을 찾을 수 없습니다.");
		} finally {
			in.close();
			out.close(); }}}





📘 Data 입출력 클래스

  • DataOutputStream : OutputStream 객체를 전달받아 원하는 자료형의 값을 원시데이타로 전달하기 위한 기능의 출력스트림을 생성하는 클래스

    • DataOutputStream.writeInt(int v) : 정수값을 출력스트림으로 전달하는 메소드
    • DataOutputStream.writeBoolean(boolean b) : 논리값을 출력스트림으로 전달하는 메소드
    • DataOutputStream.writeUTF(String s) : 문자열을 출력스트림으로 전달하는 메소드
  • DataInputStream : InputStream 객체를 전달받아 원시데이타를 원하는 자료형의 값으로 읽기 위한 기능의 입력스트림을 생성하는 클래스

    • 반드시 파일에 저장된 자료형의 순서대로 값을 읽어서 사용
    • 값을 순차적으로 읽어 사용하지 않은 경우 비정상적인 결과 발생
    • DataInputStream.readInt() : 입력스트림의 원시데이타를 정수값으로 읽어와 반환하는 메소드
    • DataInputStream.readBoolean() : 입력스트림의 원시데이타를 논리값으로 읽어와 반환하는 메소드
    • DataInputStream.readUTF() : 입력스트림의 원시데이타를 문자열로 읽어와 반환하는 메소드

🐣 자료형의 값을 원시데이터로 전달

public class DataOutputStreamApp {
	public static void main(String[] args) throws IOException {
		DataOutputStream out=new DataOutputStream(new FileOutputStream("c:/data/data.txt"));

		out.writeInt(100);
		out.writeBoolean(true);
		out.writeUTF("홍길동");//UTF : 문자 조합형

		out.close();
		
		System.out.println("c:\\data\\data.txt 파일에 여러 자료형의 값들을 저장"); }}





🐣 원시데이터를 자료형의 값으로 read

public class DataInputStreamApp {
	public static void main(String[] args) throws IOException {

		DataInputStream in=new DataInputStream(new FileInputStream("c:/data/data.txt"));

		int value1=in.readInt();
		boolean value2=in.readBoolean();
		String value3=in.readUTF();
		
		System.out.println("value1 = "+value1);
		System.out.println("value2 = "+value2);
		System.out.println("value3 = "+value3);
		
		in.close(); }}





📘 Object 입출력 클래스

  • ObjectOutputStream : OutputStream 객체를 전달받아 원하는 형태의 객체를 원시데이타로 전달하기 위한 기능의 출력스트림을 생성하는 클래스

    • ObjectOutputStream.writeObject(Object o) : 출력스트림으로 객체를 전달하기 위한 메소드
  • ObjectInputStream : InputStream 객체를 전달받아 원시데이타를 원하는 형태의 객체로 읽기 위한 기능의 입력스트림을 생성하는 클래스

    • ObjectInputStream.readObject() : 입력스트림의 원시데이타를 객체로 읽어 반환받아 메소드
    • Object 객체 타입으로 반환 ( 명시적 객체 형변환 후 사용 가능 )

🐣 객체를 원시데이터로 전달

public class ObjectOutputStreamApp {
	public static void main(String[] args) throws IOException {
		ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("c:/data/object.txt"));
		out.writeObject("홍길동");	//String 객체 전달
		out.writeObject(new Date());//Date 객체 전달
		out.writeObject(Arrays.asList("임꺽정","전우치","일지매"));//ArrayList 객체 전달
		
		out.close();
		
		System.out.println("c:\\data\\object.txt 파일에 여러개의 객체 저장"); }}
		//파일이 깨진것이 아니라 메모장이 파일을 읽어들이는 방식이 잘못됨





🐣 원시데이터를 객체로 read

public class ObjectInputStreamApp {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		ObjectInputStream in=new ObjectInputStream(new FileInputStream("c:/data/object.txt"));
		
		String string=(String)in.readObject();
		Date date=(Date)in.readObject();
		@SuppressWarnings("unchecked")
		List<String> list=(List<String>)in.readObject();
		
		//클래스의 toString() 메소드가 자동 호출되어 객체에 저장된 값이 문자열로 반환되어 출력
		System.out.println("string = "+string);
		System.out.println("date = "+date);
		System.out.println("list = "+list);
		
		in.close();





🌼 객체 직렬화

  • 객체 직렬화(Object Serialization) : 객체를 byte 배열(원시데이타의 모임)로 변환하여 입력 또는 출력 처리하기 위한 기능을 제공
  • 원시데이터를 하나의 객체로 만들어 주기 위해서 객체 직렬화 처리 필요
  • 객체 직렬화 클래스는 클래스를 구분하기 위해 식별자를 저장하는 serialVersionUID 필드를 선언하는 것을 권장
    • 이클립스에서는 serialVersionUID 필드값을 자동으로 생성하는 기능 제공 (자동으로 식별자를 만들어서 입출력시 용이)
  • String, Date, ArrayList 클래스는 Serializable 인터페이스를 상속받고 있음 (객체 직렬화 클래스)
  • 파일을 이용해서 파일을 직접 데이터 수정하는 것보다 메모리에서 arraylist를 이용하여 crud한 후 저장하는것이 더 효율적
  • NotSerializableException : 객체 직렬화 처리하지 않은 클래스의 객체를 출력스트림으로 전달할 경우 발생되는 예외
    • 출력스트림으로 전달할 객체의 클래스를 객체 직렬화 처리하면 예외 미발생

📌 객체 직렬화 클래스로 선언

  1. Serializable 인터페이스(추상메소드 없음)를 상속받아 선언

    • 객체의 모든 필드값을 byte 배열로 변환하여 입력 또는 출력 처리
  2. Externalizable 인터페이스(추상메소드 2가지)를 상속받아 선언

  • writeExternal(ObjectOutput out) 메소드와 readExternal(ObjectInput in) 메소드를 오버라이드 선언
  • 오버라이드 선언된 메소드에서 원하는 필드값을 byte 배열로 변환하여 입력 또는 출력 처리 (선별하여 효율성 높임)

🎀 연습문제 (회원정보)

🐣 예제1

  • 회원정보(아이디,이름,전화번호)를 저장하기 위한 클래스
  • 객체 단위로 입력 또는 출력 처리하는 클래스는 반드시 객체 직렬화 클래스로 선언

public class Member implements Serializable {
	//이클립스에서는 식별자를 저장하는 serialVersionUID 필드값을 자동으로 생성하는 기능 제공
	private static final long serialVersionUID = -3306639107947980039L;
	
	private String id;
	private String name;
	private String phone;
	
	public Member() { }

	public Member(String id, String name, String phone) {
		super();
		this.id = id;
		this.name = name;
		this.phone = phone;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	@Override
	public String toString() {
		return "아이디 = "+id+", 이름 = "+name+", 전화번호 = "+phone; }}





🐣 예제2

  • 회원정보(Member 객체)를 파일에 전달하여 저장하는 프로그램
public class MemberSaveApp {
	public static void main(String[] args) throws IOException {
		ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("c:/data/member.txt"));
		
		//ObjectOutputStream.writeObject(Object o) 메소드 호출시 NotSerializableException 발생
		// → 출력스트림으로 전달할 객체의 클래스를 객체 직렬화 처리하면 예외 미발생
		out.writeObject(new Member("abc123", "홍길동", "010-1324-4321"));
		out.writeObject(new Member("xyz789", "임꺽정", "010-4531-7888"));
		out.writeObject(new Member("lkj456", "전우치", "010-4654-2454"));
		
		out.close();
		
		System.out.println("c:\\data\\object.txt 파일에 회원정보를 저장 하였습니다."); }}





🐣 예제3

  • 파일에 저장된 회원정보를 읽어 출력하는 프로그램
public class MemberLoadApp {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		ObjectInputStream in=new ObjectInputStream(new FileInputStream("c:/data/member.txt"));
		
		System.out.println("<<회원목록>>");
		while(true) {
			try {
		//ObjectInputStream.readObject() 메소드 호출시 파일 커서가 EOF 위치에 있을 경우 EOFException 발생
				Member member=(Member)in.readObject();
				System.out.println(member);		//Member.toString() 메소드 자동 호출
			} catch (EOFException e) {
				break;}}
		in.close(); }}





profile
Study Log 📂

0개의 댓글

관련 채용 정보