💻 수업정리 (2020)/자바

[6/8] java.io패키지

주다람 2020. 6. 8. 19:01
  • 스트림은 확장가능하다 -> 확장클래스때문에 어렵고 복잡하다.
  • 입출력은 클래스라기보다 스트림이라는 표현을 많이 쓴다.
  • 한방향으로만 데이터를 순차적으로 전달한다.
  • ByteStream : 데이터를 바이트단위로 전달한다.
  입력클래스 출력클래스
ByteStream
원시데이터
1) 가장 기본클래스 :
- InputStream /FileInputStream
-독립적으로 사용가능

2) 확장 클래스(독립x)
- BufferedInputStream : 대용량 확장
- DataInputStream : 데이터 유형별로 전달
- ObjectInputStream : Data보다 많이 씀
1) 가장 기본클래스 :
- OutPutStream / FileOutputStream

2) 확장 클래스(독립x)
- BufferedOutputStream : 대용량 확장
- DataOutputStream : 데이터 유형별로 전달
- ObjectOutputStream : Data보다 많이 씀
- PrintStream : 사용할 수 있는 메소드가 더 많음
Character Stream
변형된 데이터
1) 기본클래스
Reader           FileReader (인스턴스 생성 불가)

                                                   

2) 확장클래스

- InputStreamReader(확장) -> BufferedReader(더확장ㅇ)
1) 기본클래스
Writer            ⇦        FileWriter/PrintWriter

                                           

2) 확장클래스
-OutputStreamWriter    ->     BufferedWriter

 

 

1) ByteStream사용해보기

package site.itwill.io;

import java.io.IOException;

//키보드로 입력값을 원시데이터(1byte)로 제공받아 모니터에 전달하는 프로그램
//=> EOF(End Of File의 약자 : 여기서는 입력종료 ctrl + z)를 입력하면 프로그램이 종료되게 만든다
public class ByteStreamApp {
	public static void main(String[] args) throws IOException {
		System.out.println("[메세지]키보드를 출력 값을 입력해 주세요(종료 : ctrl + z)");
		
		//키보드 입력값을 입력스트림에서 제공받아 저장하기 위한 변수
		int readByte;
		
		while(true) {
			//System.in : 자바에서 기본적으로 제공되는 키보드 입력 스트림
			//=> InputStream 클래스로 생성된 인스턴스
			//=> InputStream.read() : 입력스트림의 값을 원시데이터로 읽어 반환하는 메소드
			// => 입력스트림에 값이 존재하지 않을 경우 스레드가 일시중지
			//=>키보드를 눌러 스트림에 입력값 전달 후 엔터를 눌러 스레드를 재실행
			//=>모든 입출력 클래스의 메소드에서는 IOException예외처리
			//=> IOException : 입력스트림 또는 출력스트림에 문제가 있을 경우 생기는 예외
			readByte = System.in.read();
			
			//입력종료 관련 정보(ctrl + z)가 전달된 경우, 반복문을 종료
			if(readByte == -1) break;//자바에서는 입력종료를 -1로 저장한다.
			
			
			//System.out : Java에서 기본적으로 제공되는 모니터 출력스트림
			//=> PrintStream 클래스로 생성된 인스턴스(outputstream클래스를 상속받은 자식클래스)
			//outputstream.writer(int b) : 값을 원시데이터로 출력스트림으로 전달하는 메소드
			System.out.write(readByte);
			
		}
		
		System.out.println("[메세지]프로그램을 종료합니다.)");
	}
}

 

2) CharacterStream사용해보기

  • out.writer() : 이 메소드는 출력버퍼에 데이터를 모으기만 한다.
  • out.flush()메소드를 꼭 써주어야 한다. -> 출력버퍼에 저장된 문자데이터(인코딩된 문자데이터) 를 바로바로 출력하기 위해서
package site.itwill.io;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

//키보드로 입력값을 원시데이터(1byte)로 제공받아 모니터에 전달하는 프로그램
//=> 문자데이터 : 원시데이터를 인코딩하여, 변형한 데이터
//=> EOF(End Of File의 약자 : 여기서는 입력종료 ctrl + z)를 입력하면 프로그램이 종료되게 만든다
public class CharacterStreamApp {
	
	public static void main(String[] args) throws IOException {
		System.out.println("[메세지]키보드를 출력 값을 입력해 주세요(종료 : ctrl + z)");
		
		//InputStreamReader : 문자데이터로 읽기 위한 기능을 제공하는 클래스
		//=> InputStream 인스턴스를 전달받아야 입력스트림생성가능
		InputStreamReader in = new InputStreamReader(System.in);
		
		//OutputStreamWriter : 문자데이터로 전달하기 위한 기능을 제공하는 클래스
		//=>OutputStream : 인스턴스를 전달받아야 출력스트림생성가능
		OutputStreamWriter out = new OutputStreamWriter(System.out);
		
		int readByte;
		while(true) {
			//입력스트림의 입력값을 인코딩 처리하여 문자데이터로 반환받아 저장
			readByte = in.read();
			
			if(readByte == -1) break;
			
			//문자데이터를 출력스트림으로 전달하여 출력처리
			//=> writer관련 문자데이터를 출력하는 스트림은 출력버퍼에 데이터를 모아 한번에 출력스트림에 전달
			out.write(readByte);
			
			//출력버퍼에 저장된 문자데이터를 출력스트림에 전달
			out.flush();//★꼭써줘야함
		}
		
		System.out.println("[메세지]프로그램을 종료합니다.)");
	}
}

 

 

 

3)  문자열을 입력받을 수 있도록 확장하여 저장해보기

  • 키보드 입력스트림으로 문자열을 입력받을 수 있도록 확장하여 저장
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

 

  • InputStreamReader : 문자데이터를 읽기 위한 입력스트림으로 확장하는 클래스
  • InputStream : 원시데이터를 읽기위한 InputStream인스턴스를 전달받아 확장처리한다.
  • BufferedReader : 대용량처리를 위한 입력스트림으로 확장하는 클래스
  • Reader : 인스턴스를 전달받아 확장
package site.itwill.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;

//키보드로 이름과 태어난 년도를 입력받아 이름과 나이를 계산하여 출력
public class ConsoleIOApp {
	public static void main(String[] args) throws IOException {
		//키보드 입력스트림으로 문자열을 입력받을 수 있도록 확장하여 저장 
		//System.in : 키보드로 원시데이터를 읽기위한 입력스트림
		//=> InputStreamReader : 문자데이터를 읽기위한 입력스트림으로 확장하는 클래스
		//=> InputStream : 원시데이터를 읽기위한 InputStream인스턴스를 전달받아 확장처리
		//=> BufferedReader : 대용량처리를 위한 입력스트림으로 확장하는 클래스
		//=> Reader : 인스턴스를 전달받아 확장
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//문자열입력가능
		
		//PrintStream클래스의 print()또는 println()메소드를 이용할
		//경우 모든 형태의 값을 문자열로 변환되어 출력스트림으로 전달
		System.out.print("이름입력 >> ");
		
		//BufferedReader.readLine() : 입력스트림에 존재하는 모든 문제데이터를 문자열로 반환하는 메소드
		String name = br.readLine();
		
		System.out.print("태어난 년도 입력 >> ");
		//입력값을 문자열로 변환받아 정수값으로 변환하여 저장
		int year = Integer.parseInt(br.readLine()); 
		
		int age = Calendar.getInstance().get(Calendar.YEAR)-year +1;
		
		System.out.println("[결과] "+ name +"님의 나이는 " + age );
	}
}

 

 

4) File 클래스 가지고 탐색해보기

package site.itwill.io;

import java.io.File;
import java.io.IOException;

//File클래스  : 파일 정보를 저장하기 위한 클래스
//=> 폴더 (디렉토리)도 파일로 인식되어 저장 가능
public class FileApp {
	public static void main(String[] args) throws IOException {
		//File(String pathname) : 파일 경로를 전달받아 File인스턴스를 생성하는 생성자
		//파일 경로(FilePath) : 파일 위치를 표현하기 위한 표현방법
		//=> 절대경로 표현방법 및 또는 상대 경로 표현방법이 있음
		//=> 절대경로 : 최상위 디렉토리를(드라이브) 기준으로 파일의 위치를 표현하는 방법 
		//=> 상대경로 : 현재 실행 프로그램의 위치(프로젝트 디렉토리)를 기준으로 파일의 위치를 표현하는 방법
		//윈도우즈 운영체제에서는 디렉토리 구분자로 역슬레시 사용 -> 이것을 자바에서는 이스케이프 문자를 표현하는 기호이다.
		//=> 디렉토리 구분자로 사용하려면 역슬레시를 두번 써야 함
		File file = new File("c:\\data");
		
		//File.exists() : File 인스턴스에 저장된 파일 경로에 
		//실제 파일이 없는 경우 false, 존재할 경우 true
		if(file.exists()) {
			System.out.println("c:\\data 폴더 디렉토리가 존재합니다.");
		}else {
			//file.mkdir() : File 인스턴스에 저장된 파일 경로로 디렉터리를 생성하는 메소드
			file.mkdir();
			System.out.println("c:\\data 폴더 디렉토리를 생성했습니다.");			
			
		}
		System.out.println("==========================================================");
		
		//디렉토리 구분자로 슬래시를 사용하는 것을 권장
		File file2 = new File("c:/data/abc.txt");
		
		if(file2.exists()) {
			System.out.println("c:\\data\\abc.txt 파일이 존재합니다.");
		}else {
			//file.createNewFile() : File 인스턴스에 저장된 파일 경로로 파일을 생성하는 메소드
			//IOExceptionqkftod - 예외처리를 해주어야 함
			file2.createNewFile();
			System.out.println("c:\\data\\abc.txt 파일을 생성했습니다.");			
		}
		System.out.println("==========================================================");
		
		//file(file parent, String child) 생성자 또는 File(String parents,String child)
		//=> 파일경로를 부모(디렉토리)와 자식(파일)으로 전달하여 파일인스턴스를 생성
		File file3 = new File("c:/data/xyz.txt");
		//File file4 = new File("c:/data","xyz.txt");
		//File file4 = new File(file,"xyz.txt"); 도 가능하다.
		
		if(file3.exists()) {
			file3.delete();
			System.out.println("c:\\data\\xyz.txt 파일을 삭제했습니다.");			
			
		}else {
			System.out.println("c:\\data\\xyz.txt 파일이 존재하지않습니다.");			
			
		}
		System.out.println("==========================================================");
		
		File file4 = new File("https://github.com/jooy311/itwill_java_oracle_javascript/tree/master/java-3/src/site/itwill");
		if(file4.exists()) {
			//File.toStrint() : 파일경로를 문자열로 표현
			System.out.println("파일경로 = " +file4.getAbsolutePath());
			//File.getAbsolutePath() : 파일 인스턴스에 저장된 파일경로를 절대경로의 문자열로 변환하여 반환하는 메소드 
		}else {
			System.out.println("작업디렉토리가 존재하지않습니다(깃헙에 저장되어 있어요 ㅠㅠ.");			
			
		}
		System.out.println("==========================================================");
		
		File file5 = new File("c:/");
		
		//isDirectory() : File인스턴스에 저장된 파일경로의 파일이
		//디렉토리가 아닌경우false반환, 디렉토리인 경우 true를 반환
		if(file5.isDirectory()) {
			//File.listFiles() : File 인스턴스에 저장된 파일경로의 자식파일 목록을 File인스턴스배열로 반환하는 메소드
			File[] subFiles = file5.listFiles();
			
			System.out.println(file5 + "디렉토리의 자식목록 >> ");
			for(File files : subFiles) {
				//파일 인스턴스에 저장된 파일경로의 데이터파일이 아닌경우 false, 데이터 파일인 경우 true반환
				//
				if(files.isFile()) {
					System.out.println("일판파일 = " + files);
				}else {
					System.out.println("숨김파일" + files);
				}
			}
			
		}else {
			
		}
		System.out.println("==========================================================");
	}
}

 

 

File처리

 

5) 파일 처리 - 파일을 load하고 save해보기

-파일에 저장된 값을 원시데이터로 읽어 모니터에 전달하여 출력하는 프로그램

파일 save
  • 파일 출력스트림(FileOutputStream)을 생성하기 위한 클래스를 생성해 준다.
  • FileOutputStream fo = new FileOutputStream("절대 경로");
  • 파일경로를 전달하여 출력스트림을 생성해 주면됨
  • 파일 경로에 파일이 없다면? - 파일을 자동으로 생성하여 출력스트림을 만든다
  • 파일이 경로에 이미 있다면 ? - 오버라이드 즉, 덮어씌워진다.
package site.itwill.io;

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

//키보드 입력값을 원시데이터로 읽어 파일에 전달하여 저장하는 프로그램
// => ctrl +z 를 전달하기 전까지 반복실행
public class ByteSaveApp {
	public static void main(String[] args) throws IOException {
		System.out.println("[메세지]키보드를 출력 값을 입력해 주세요(종료 : ctrl + z)");
		
		//파일 출력스트림을 생성하기 위한 클래스
		//=> 파일경로를 전달하여 출력스트림을 생성해주면 됨
		//=> 파일 경로에 파일이 없는 경우 FileNotFoundException이 발생할 수 있음
		//=> FileNotFoundException : IOException의 자식 예외클래스
		//=> 예외처리(checked Exception)
		//=> 파일이 없는 경우 파일을 자동으로 생성하여 출력스트림을 만든다.
		//=> 파일이 있는 경우 기존내용 대신 새로운 내용을 파일에 저장 - overwrite
		
		// 파일경로와 true값을 전달할 경우, 기존내용뒤에 새로운내용을 추가하는 파일 출력스트림을 생성
		FileOutputStream fo = new FileOutputStream("c:/data/byte.txt", true);
		
		int readByte;
		while(true) {
			readByte = System.in.read();
			if(readByte == -1) break;
			
			//save
			fo.write(readByte); //파일이 저장됨
			
		}
		//파일에는 입력또는 출력스트림을 각각 하나씩만 생성이 가능함
		//=> 파일처리를 위해 생성된 스트림은 사용후 반드시 제거!!!! -> 다른 프로그램에서 스트림을 사용할 때 문제가 생김
		//FileOutputStream.close() : 파일 출력스트림을 제거하는 메소드
		fo.close();//★꼭해주기
		
		System.out.println("[메세지] 파일에 키보드 입력값이 저장되었습니다.");
	}
}

 

파일 Load
  • 파일 입력스트림(FileInputStream)을 생성하기 위한 클래스를 생성해준다.
  • FileInputStream in = new FileInputStream("경로");
  • 파일 경로를 전달하여 출력 스트림을 생성해 주면 됨
package site.itwill.io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

//파일에 저장된 값을 원시데이터로 읽어 모니터에 전달하여 출력하는 프로그램
public class FileByteLoadApp {
	public static void main(String[] args) throws IOException {
		System.out.println("[메세지] c:\\data\\byte.txt 파일에 저장된 내용입니다.");
		
		//FileInputStream : 파일 입력스트림을 생성하기 위한 클래스
		//=> 파일 경로를 전달하여 파일 입력스트림을 생성
		
		FileInputStream in = null;
		
		try {
			in = new FileInputStream("c:/data/byte.txt ");
			int readByte;
			
			while(true) {
				//Load
				readByte = in.read();//파일 데이터를 읽어 변수에 저장
				
				//파일 마지막에는 EOF가 존재(우리눈에는 보이지 않음)
				if(readByte == -1) break;
				
				System.out.write(readByte);
				
			}
			
		} catch (FileNotFoundException e) {
			System.out.println("[에러]원본파일이 존재하지 않습니다.");
		}finally {
			if(in != null ) in.close(); //nullPointerException을 방지하기 위함
		}
		
				
	}
}

 

 

4) 파일 처리 - 파일을 load하고 save해보기(문자데이터)

-파일에 저장된 값을 문자데이터를 읽어 모니터에 전달하여 출력하는 프로그램

파일 save
  • FileWriter : 파일 출력스트림을 생성하기 위한 클래스 
  • 문자데이터를 전달받아 파일에 저장하는 출력스트림 - 텍스트
package site.itwill.io;

import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;


//키보드로 입력값을 문자데이터로 제공받아 모니터에 전달하는 프로그램
//=> EOF(End Of File의 약자 : 여기서는 입력종료 ctrl + z)를 입력하면 프로그램이 종료되게 만든다
public class FileCharSaveApp {
	public static void main(String[] args) throws IOException {
		System.out.println("[메세지]키보드를 출력 값을 입력해 주세요(종료 : ctrl + z)");
		InputStreamReader in = new InputStreamReader(System.in);
		//FileWriter : 파일 출력스트림을 생성하기 위한 클래스 
		//=>문자데이터를 전달받아 파일에 저장하는 출력스트림 - 텍스트
		FileWriter out = new FileWriter("c:/data/char.txt",true);
		
		int readByte;
		while(true) {
			
			readByte = in.read();
			if(readByte == -1) break;
			out.write(readByte);
		}
		out.close();
		
		System.out.println("파일에 저장됐다 ");
	}
}

 

 

파일 load
  • FileReader : 파일 입력스트림을 생성하기 위한 클래스
  • 파일 내용을 문자데이터로 읽기위한 입력스트림 생성
  • in = new FileReader("경로");
  • 문자데이터로 모니터에 전달하기 위한 출력스트림
  • OutputStreamWriter out = new OutputStreamWriter(System.out);

 

6) 파일처리 - 대용량 스트림으로 확장하는 클래스 이용하기

- 원본파일에 저장된 값을 원시데이타로 읽어 타겟파일에 전달하여 저장하는 프로그램
- 모든 파일 복사 가능하다

 

  • BufferedInputStream : 입력스트림을 전달받아 대용량 입력스트림으로 확장하는 클래스
  • BufferedOutputStream : 출력스트림을 전달받아 대용량 출력스트림으로 확장하는 클래스
package site.itwill.io;

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

//원본파일에 저장된 값을 원시데이타로 읽어 타겟파일에 전달하여 저장하는 프로그램
// => 모든 파일 복사 가능
public class FileByteCopyApp {
	public static void main(String[] args) throws IOException {
		//BufferedInputStream : 입력스트림을 전달받아 대용량 입력스트림으로 확장하는 클래스
		BufferedInputStream in=null;
		//BufferedOutputStream : 출력스트림을 전달받아 대용량 출력스트림으로 확장하는 클래스
		BufferedOutputStream out=null;
		try {
			
			//in=new BufferedInputStream(new FileInputStream("c:/data/setup.txt"));
			in=new BufferedInputStream(new FileInputStream("c:/data/setup.exe"));
			
			//out=new BufferedOutputStream(new FileOutputStream("c:/data/setup_byte.txt"));
			out=new BufferedOutputStream(new FileOutputStream("c:/data/setup_byte.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 {
			if(in!=null) in.close();
			if(out!=null) out.close();
		}
	}
}








 

 

7) 파일처리 - 대용량 스트림으로 확장하는 클래스 이용하기

- 원본파일에 저장된 값을 문자데이터로 읽어 타겟파일에 전달하여 저장하는 프로그램

- 텍스트 파일만 복사가 가능함
- 일반파일은 변형된 데이터가 되므로 깨지게 됨 

 

package site.itwill.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

//원본파일에 저장된 값을 문자데이터로 읽어 타겟파일에 전달하여 저장하는 프로그램
//=>텍스트 파일만 복사가 가능함
//=>일반파일은 변형된 데이터가 되므로 깨지게 됨 
public class FileCharCopyApp {
	public static void main(String[] args) throws IOException {
		BufferedReader in = null;
		BufferedWriter out = null;
		
		try {
			//in = new BufferedReader(new FileReader("c:/data/setup.txt"));
			in = new BufferedReader(new FileReader("c:/data/setup.exe"));
			//out = new BufferedWriter(new FileWriter("c:/data/setup_char.txt"));
			out = new BufferedWriter(new FileWriter("c:/data/setup_char.exe"));
			
			int readByte;
			while(true) {
				readByte = in.read();
				if(readByte == -1) break;
				out.write(readByte);
				out.flush();
			}
			

		} catch (FileNotFoundException e) {
			
			System.out.println("[에러]원본파일이 존재하지 않습니다.");
			
		} finally {
			if (in != null)
				in.close(); // nullPointerException을 방지하기 위함
		}
	}
}