File IO / Stream

Agnes Park·2022년 3월 13일
0

JAVA

목록 보기
33/34

1. IO(Input/Output)

package com.lec.java.file01;

import java.util.Scanner;

/* 스트림 (stream)
	[도착지]							[출발지]
	Program <--- InputStream <--- Source(Keyboard, Mouse, File, Network)
	
	[출발지]							[도착지]
	Program ---> OutputStream ---> Destination(Monitor, Beam, File, Network)


java.io 패키지의 주요 클래스

1) 바이트(byte) 단위 입출력 스트림 클래스
	java.io.InputStream: 프로그램이 '바이트 단위' 데이터를 읽어들이는(read) 통로
	java.io.OutputStream: 프로그램이 '바이트 단위' 데이터를 쓰는(write) 통로
		** 위 두개 클래스는 '추상클래스' 다
	
2) 문자(character) 단위 입출력 스트림 클래스
	java.io.Reader: 프로그램이 '문자 단위' 데이터를 읽어들이는(read) 통로
	java.io.Writer: 프로그램이 '문자 단위' 데이터를 쓰는(write) 통로

3) java.io.File : 파일 시스템의 파일정보를 얻기 위한 클래스
	
4) java.io.Console : 콘솔로부터 문자을 입출력하기 위한 클래스
*/

public class File01Main {

	public static void main(String[] args) {
		System.out.println("IO(Input/Output)");
		
		// InputStream 객체 in을 가지고 읽어들일 수 있는 스캐너 객체 생성
		Scanner sc = new Scanner(System.in);
		
		// 외부장치(콘솔, 키보드)로부터 데이터를 읽음
		String msg = sc.nextLine();
		
		sc.close();
		
		// OutpustStream 객체인 out이 가지고 있는 println() 메소드를 사용
		// 외부장치(콘솔, 모니터)에 데이터를 씀
		System.out.println(msg);
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

2. Input/OutputStream

package com.lec.java.file02;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/* FileIO
 Program <=== InputStream <=== Source
 Program ===> OutputStream ===> Source
 Program <=== FileInputStream <=== File
 Program ===> FileOutputStream ===> File

 java.io.InputStream
  |__ java.io.FileInputStream: 파일로부터 데이터를 읽어오는 통로
 java.io.OutputStream
  |__ java.io.FileOutputStream: 파일로 데이터를 쓰는 통로
*/

public class File02Main {

	public static void main(String[] args) {
		System.out.println("File IO");

		InputStream in = null; 
		OutputStream out = null;
		
		try {
			// FileInputStream 인스턴스 생성
			in = new FileInputStream("temp/big_text.txt");
			
			// fileOutputStream 인스턴스 생성
			// 해당 파일이 없으면, 새로 생성.
			// ..		있었으면, 지우고 새로 생성.
			out = new FileOutputStream("temp/copy_big_text.txt");
			
			// 파일복사
			// InputStream에서 한 byte 씩 읽어 들여와서
			// OutputStream에 한 byte 씩 쓰기.
			int dataRead;
			int byteCopied = 0;
			long startTime = System.currentTimeMillis();	// 현재 시간 저장
			while(true) {
				// 데이터 읽기: InputStream에 있는 read() 메소드 사용
				// read()는 InputStream 으로부터 
				// 1byte 씩 읽어서 int(4byte) 에 담아 리턴한다
				// [ ... ][ ... ][ ... ][ 1byte ]
				dataRead = in.read();
				if(dataRead == -1) {	// 더이상 읽을 것이 없으면 read() 는 -1 을 리턴한다.
					break;
				}
				
				// 데이터 쓰기: OutputStream에 있는 write() 메소드 사용
				// write() 는 
				// int(4byte)에 1byte씩 담아 OutputStream에 쓴다
				// [ ... ][ ... ][ ... ][ 1byte ]
				out.write(dataRead);
				byteCopied++;
			} // end while
			
			long endTime = System.currentTimeMillis(); 	// 끝난 시간 저장
			long elapsedTime = endTime - startTime;	// 경과 시간
			
			System.out.println("읽고 쓴 바이트: " + byteCopied);
			System.out.println("경과 시간(ms): " + elapsedTime);
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 리소스 해제
			try {
				if(out != null) out.close();
				if(in != null) in.close();
			} catch (IOException e ) {
				e.printStackTrace();
			}
		}
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

3. Input/OutputStream + Buffer

package com.lec.java.file03;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/*
 java.io.InputStream
  |__ java.io.FileInputStream
 java.io.OutputStream
  |__ java.io.FileOutputStream
*/

public class File03Main {

	public static void main(String[] args) {
		System.out.println("File IO 2");
		
		// Java 7부터 도입된 try-with-resource
		// try (리소스 생성) { ... }
		// catch (exception ) { ... }
		// 리소스를 close하는 코드가 없어도 자동으로 close가 실행
		//
		// java.lang.AutoCloseable 나 
		//  └─ java.io.Closeable 을 상속받은 어떠한 객체라도 
		//  try(리소스 생성) 안에 '선언' 되어 있으면
		//  try~catch 가 끝나기 전에 close() 됨.
		
		// InputStream, OutputStream 둘다 Closeable 을 상속(implements) 한다
		
	
		try(
				// FileInputStream 생성
				InputStream in = new FileInputStream("temp/big_text.txt");
				OutputStream out = new 		
                FileOutputStream("temp/copy_big_text.txt");
				){
			
			byte[] buff = new byte[1024];	// 버퍼 준비
			
			int lengthRead = 0;	// 버퍼에 담긴 byte수
			int byteCopied = 0;
			
			long startTime = System.currentTimeMillis();
			
			// 파일복사
			while(true) {
				// 데이터 읽기
				
				// 매개변수로 주어진 byte[] 배열의 길이 만큼 read한다.
				// 실제 읽어 들인 데이터는 매개변수 byte[] 에 담김.
				// 읽어들인 바이트 개수 리턴,  읽어들인게 없으면 -1 리턴.
				lengthRead = in.read(buff);
				if(lengthRead == -1) {	// 더이상 읽어드릴 것이 없으면 종료
					break;
				}
				
				// 데이터 쓰기
				out.write(buff, 0, lengthRead);	// 직전에 읽어드린 데이터만큼 write
				
				byteCopied += lengthRead;		
			}
			
			long endTime = System.currentTimeMillis();
			long elapsedTime = endTime - startTime;
			
			System.out.println("전체 복사한 바이트: " + byteCopied);
			System.out.println("경과 시간: " + elapsedTime);
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

4. I/O + Buffered I/O Stream


package com.lec.java.file04;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/* 보조스트림 (filter stream) : 기존 스트림에 추가적인 동작을 구현한 스트림
Program <=== FilterInputStream <=== InputStream <=== Source
					↓ 상속					↓ 상속
Program <=== BufferedInputStream <=== FileInputStream <=== File

Program ===> FilterOutputStream ===> OutputStream ===> Source
					↓ 상속					↓ 상속
Program ===> BufferedOutputStream ===> FileOutputStream ===> File

java.io.InputStream
 |__ java.io.FilterInputStream
      |__ java.io.BufferedInputStream

java.io.OutputStream
 |__ java.io.FilterOutputStream
      |__ java.io.BufferedOutputStream

참고 ) 보조스트림 (filter stream)
보조스트림(filter stream) 이란 다른 스트림과 연결되어 여러가지 편리한 기능을 제공해주는 스트림
*/

public class File04Main {

	public static void main(String[] args) {
		System.out.println("BufferedInputStream, BufferedOutputStream");

		InputStream in = null;
		BufferedInputStream bin = null;
		OutputStream out = null;
		BufferedOutputStream bout = null;
		
		try {
			// FileInputStream 인스턴스 생성
			in = new FileInputStream("temp/big_text.txt");
			bin = new BufferedInputStream(in);	// 장착!
			
			// fileOutputStream 인스턴스 생성
			// 해당 파일이 없으면, 새로 생성.
			// ..		있었으면, 지우고 새로 생성.
			out = new FileOutputStream("temp/copy_big.text.txt");
			bout = new BufferedOutputStream(out);	// 장착!
			
			// in.read() 대신에 bin.read() 를
			// out.write() 대신에 bout.write() 를 사용하면 된다.
			// finally 꼭!
			
			// 파일복사
			int dataRead;
			int byteCopied = 0;
			long startTime = System.currentTimeMillis();	// 현재 시간 저장
			while(true) {
				// 데이터 읽기: InputStream에 있는 read() 메소드 사용
				// read()는 InputStream 으로부터 
				// 1byte 씩 읽어서 int(4byte) 에 담아 리턴한다
				// [ ... ][ ... ][ ... ][ 1byte ]
				dataRead = bin.read();
				if(dataRead == -1) {
					break;
				}
				
				bout.write(dataRead);
				byteCopied++;
			} // end while
			
			long endTime = System.currentTimeMillis(); 	// 끝난 시간 저장
			long elapsedTime = endTime - startTime;	// 경과 시간
			
			System.out.println("읽고 쓴 바이트: " + byteCopied);
			System.out.println("경과 시간(ms): " + elapsedTime);
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 리소스 해제
			try {
				if(bout != null) bout.close();
				if(in != null) bin.close();
				// bin을 close() 하면 bin이 장착된 in 도 함께 close된다.
			} catch (IOException e ) {
				e.printStackTrace();
			}
		}
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

5. I/O + Buffered I/O Stream + Buffer

package com.lec.java.file05;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/* Buffered Stream + Buffer 예제
Program <=== FilterInputStream <=== InputStream <=== Source
					↓ 상속					↓ 상속
Program <=== BufferedInputStream <=== FileInputStream <=== File

Program ===> FilterOutputStream ===> OutputStream ===> Source
					↓ 상속					↓ 상속
Program ===> BufferedOutputStream ===> FileOutputStream ===> File

java.io.InputStream
 |__ java.io.FilterInputStream
      |__ java.io.BufferedInputStream

java.io.OutputStream
 |__ java.io.FilterOutputStream
      |__ java.io.BufferedOutputStream
*/

public class File05Main {

	public static void main(String[] args) {
		System.out.println("Buffered Stream + Buffer");
		
		// TODO:
		// file03 패키지 참조
		// try with resource 구문으로 작성
		// in.read(buff) --> bin.read(buff);
		// out.write( , , ) --> bout.write( , , ); 사용
		// finally 필요 없슴
		
		
		try(
				// FileInputStream 생성
				InputStream in = new FileInputStream("temp/big_text.txt");
				BufferedInputStream bin = new BufferedInputStream(in);	// 장착
				OutputStream out = new FileOutputStream("temp/copy_big_text.txt");
				BufferedOutputStream bout = new BufferedOutputStream(out);
				){
			
			byte[] buff = new byte[1024];	// 버퍼 준비
			
			int lengthRead = 0;	// 버퍼에 담긴 byte수
			int byteCopied = 0;
			
			long startTime = System.currentTimeMillis();
			
			// 파일복사
			while(true) {
				// 데이터 읽기
				
				// 매개변수로 주어진 byte[] 배열의 길이 만큼 read한다.
				// 실제 읽어 들인 데이터는 매개변수 byte[] 에 담김.
				// 읽어들인 바이트 개수 리턴,  읽어들인게 없으면 -1 리턴.
				lengthRead = bin.read(buff);
				if(lengthRead == -1) {	// 더이상 읽어드릴 것이 없으면 종료
					break;
				}
				
				// 데이터 쓰기
				bout.write(buff, 0, lengthRead);	// 직전에 읽어드린 데이터만큼 write
				
				byteCopied += lengthRead;		
			}
			
			long endTime = System.currentTimeMillis();
			long elapsedTime = endTime - startTime;
			
			System.out.println("전체 복사한 바이트: " + byteCopied);
			System.out.println("경과 시간: " + elapsedTime);
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		System.out.println("\n프로그램 종료");

	} // end main()

} // end class File05Main

6. Data Filter Stream

package com.lec.java.file06;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/*  Data Filter Stream
 Program <=== DataInputStream <=== FileInputStream <=== File
 Program ===> DataOutputStream ===> FileOutputStream ===> File

java.io.InputStream
|__ java.io.FilterInputStream
   |__ java.io.DataInputStream  

java.io.OutputStream
|__ java.io.FilterOutputStream
   |__ java.io.DataOutputStream
*/

public class File06Main {

	public static void main(String[] args) {
		System.out.println("Data Filter Stream");
		
		try(
				OutputStream out = new FileOutputStream("temp/data.bin");
				DataOutputStream dout = new DataOutputStream(out);
				InputStream in = new FileInputStream("temp/data.bin");
				DataInputStream din = new DataInputStream(in);
				){
			dout.writeBoolean(true);	// 1 byte
			dout.writeInt(100);		// 4 byte
			dout.writeDouble(3.14);	// 8 byte
			dout.writeChar('A');	// 2 byte
			
			boolean b = din.readBoolean();
			System.out.println("boolean: " + b);
			
			int num1 = din.readInt();
			System.out.println("int: " + num1);
			
			double num2 = din.readDouble();
			System.out.println("double: " + num2);
			
			char ch = din.readChar();
			System.out.println("char: " + ch);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class

7. Object Filter Stream

[코드1]

package com.lec.java.file08;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

/* Object Filter Stream
 Program <=== ObjectInputStream <=== FileInputStream <=== File
 Program ===> ObjectOutputStream ===> FileOutputStream ===> File

java.lang.Object
 └─ java.io.OutputStream
    └─ java.io.ObjectOutputStream
 
java.lang.Object
 └─ java.io.InputStream
     └─ java.io.ObjectInputStream


 Object Stream: 객체의 입출력을 위한 스트림
 사용법은 다른 Filter Stream(Buffered I/O, Data I/O)과 비슷
 Object 스트림의 입출력 대상이 되는 클래스는 Serializable 인터페이스를 구현
 클래스의 일부 멤버 변수를 직렬화(Serialization)의 대상에서 제외시키려면,
 transient 키워드를 사용
*/
public class File08Main {
	
	public static final String FILEPATH  = "temp/member.dat";

	public static void main(String[] args) {
		System.out.println("Object Filter Stream");
		

		try(
				OutputStream out = new FileOutputStream(FILEPATH);
				ObjectOutputStream oout = new ObjectOutputStream(out);
				InputStream in = new FileInputStream(FILEPATH);
				ObjectInputStream oin = new ObjectInputStream(in);
				){
			
			// 파일에 저장할 데이터 객체 생성
			Member m1 = new Member("root", "root1234");
			Member m2 = new Member("quest", "quest");
			Member m3 = new Member("adamin", "admin123456");
			
			oout.writeObject(m1);
			oout.writeObject(m2);
			oout.writeObject(m3);
			
			// 파일에서 Object 타입으로 읽기
			Member dataRead;
			dataRead = (Member)oin.readObject();
			dataRead.displayInfo();
			dataRead = (Member)oin.readObject();
			dataRead.displayInfo();
			dataRead = (Member)oin.readObject();
			dataRead.displayInfo();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class
package com.lec.java.file08;

import java.io.Serializable;
	
public class Member implements Serializable {

	private static final long serialVersionUID = -456;
	private String id;
	private String pw;
	transient private int num;
	transient private boolean isExist;
	
	// transient로 선언된 변수는 serialization(직렬화) 대상에서 제외됨.
	// (파일에 write되지 않는다)
	// de-serializtion(역직렬화, 파일에서 읽기)를 할 때는 
	// 해당 타입의 기본값(0, false, null)으로 초기화됨
	
	public Member() {}
	public Member(String id, String pw) {
		this.id = id;
		this.pw = pw;
		this.num = 123;
		this.isExist = true;
	}
	
	public void displayInfo() {
		System.out.println("--- 회원 정보 ---");
		System.out.println("아이디: " + id);
		System.out.println("비밀번호: " + pw);
		System.out.println("번호: " + num);
		System.out.println("Exist? " + isExist);
	}
	
} // end class Member 

[코드2]

package com.lec.java.file09;

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;

// Object Filter Stream + Collection

// Program <=== ObjectInputStream <=== FileInputStream <=== File
// Program ===> ObjectOutputStream ===> FileOutputStream ===> File

// ArrayList<> 와 같은 Collection 에서,
// 모든 데이터들이 Serializable 되어 있으면 ObjectInputStream / ObjectOutputStream 으로
// read/write 가능.

public class File09Main {
	
	public static final String FILEPATH  = "temp/member2.dat";

	public static void main(String[] args) {
		System.out.println("Object Filter Stream");

		try(
				OutputStream out = new FileOutputStream(FILEPATH);
				ObjectOutputStream oout = new ObjectOutputStream(out);
				InputStream in = new FileInputStream(FILEPATH);
				ObjectInputStream oin = new ObjectInputStream(in);
				){
			
			// 리스트 준비
			ArrayList<Member> list = new ArrayList<Member>();
			
			// 파일에 저장할 데이터 객체 생성
			Member m1 = new Member("root", "root1234");
			Member m2 = new Member("quest", "quest");
			Member m3 = new Member("adamin", "admin123456");
			
			list.add(m1);
			list.add(m2);
			list.add(m3);
			
			oout.writeObject(list);	// List 를 한번에 저장
			
			list = null;
			
			list = (ArrayList<Member>)oin.readObject();
			for(Member m : list) {
				m.displayInfo();
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		
		System.out.println("\n프로그램 종료");
		
	} // end main()

} // end class File08Main
package com.lec.java.file09;

import java.io.Serializable;

public class Member implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -362426577793734250L;
	private String id;
	private String pw;
	transient private int num;
	transient private boolean isExist;
	// transient로 선언된 변수는 serialization(직렬화) 대상에서 제외됨.
	// (파일에 write되지 않는다)
	// de-serializtion(역직렬화, 파일에서 읽기)를 할 때는 
	// 해당 타입의 기본값(0, false, null)으로 초기화됨
	
	public Member() {}
	public Member(String id, String pw) {
		this.id = id;
		this.pw = pw;
		this.num = 123;    // de-serializtion 동작 확인을 위해 기본값 초기화
		this.isExist = true;
	}
	
	public void displayInfo() {
		System.out.println("--- 회원 정보 ---");
		System.out.println("아이디: " + id);
		System.out.println("비밀번호: " + pw);
		System.out.println("번호: " + num);
		System.out.println("Exist? " + isExist);
	}
	
	
} // end class Member 

Tips!
1. UTF-8 > ms949로 변경시, 한글로 보임

0개의 댓글