기록/자바_국비

[배운내용정리] 1125 자바 국비교육

mois 2020. 11. 29. 15:01
728x90

2020년 11월 25일 9시 ~ 15시 30분 zoom으로 수업 진행


 

자바 IO

 Input 과 output 의 약자, 컴퓨터 내부 또는 외부 장치와 프로그램 간의 데이터를 주고 받는 것

장치와 입출력을 위해서는 하드웨어 장치에 직접 접근이 필요한데, 다양한 매체에 존재하는 데이터들을 사용하기 위해 입출력 데이터를 처리할 공통적인 방법으로 스트림을 이용한다.

 

스트림(Stream)

 입출력 장치에서 데이터를 읽고 쓰기 위해서 자바에서 제공하는 클래스

 모든 스트림은 단방향이며 각각의 장치마다 연결할 수 있는 스트림이 존재한다

 하나의 스트림을 입출력을 동시에 수행할 수 없다(스트림은 단방향) ,

 동시에 입출력을 수행하려면 입력 스트림 하나, 출력 스트림 하나 해서 총 2개의 스트림이 필요하다

 바이트 단위는 1바이트씩 , 문자 단위는 2바이트(한 문자)

 

구분

바이트 기반 스트림

(바이트 단위 처리)

문자 기반 스트림

(문자 단위 처리)

입력 스트림

출력 스트림

입력 스트림

출력 스트림

최상위 클래스

InputStream

OutputStream

Reader

Writer

하위 클래스

XXXInputStream

XXXOutputStream

XXXReader

XXXWriter

 

기반 스트림과 보조 스트림

 자바에서 스트림을 이용해 프로그램과 입출력의 통로를 만들 때 기반 스트림으로만 통로를 열 수 있다. 보조 스트림은 통로를 꾸며준다고 생각(성능 향상, 속도 높임 등 보조적인 것)

 보조 스트림은 단독으로 사용할 수 없다.

 

InputStream

 바이트 기반 입력 스트림의 최상위 클래스 , 추상 클래스다

FileInputStream은 기반 나머지 둘은 보조 스트림

 

리턴타입

메소드

기능

int

read()

입력 스트림으로부터 1바이트를 읽고 읽은 바이트 리턴

int

read(byte[] b)

입력 스트림으로부터 읽은 바이트들ㅇ르 매개 값으로 주어진
바이트 배열 b에 저장하고 실제로 읽은 바이트 수 리턴

int

read(byte[] b, int off, int len)

입력 스트림으로부터 len개의 바이트만큼 읽고
매개 값으로 주어진 바이트 배열b[off]부터 len개 까지를 저장
실제로 읽은 바이트 수인 len개 리턴
만약 len개를 모두 읽지 못 하면 실제로 읽은 바이트 수 리턴

void

close()

사용한 시스템 자원 반납 후 입력 스트림을 닫음

 

OutputStream

 바이트 기반 출력 스트림의 최상위 클래스 , 추상 클래스

리턴 타입

메소드

기능

void

wirte(int b)

출력 스트림으로 1바이트를 보냄

void

wirte(byte[] b)

출력 스트림에 매개 값으로 주어진 바이트 배열 b의 모든 바이트를 보냄

void

wirte(byte b[], int off, int len)

출력 스트림에 매개 값으로 주어진 바이트 배열
b[off]부터 len개까지의 바이트를 보냄

void

flush()

버퍼에 잔류하는 모든 바이트 출력

void

close()

사용한 시스템 자원 반납 후 출력 스트림 닫기

 

Reader

 문자 기반 입력 스트림의 최상위 클래스 , 추상클래스

리턴타입

메소드

기능

int

read()

입력 스트림으로부터 한 개의 문자를 읽고 리턴

int

read(char[] c)

입력 스트림으로부터 읽은 문자들을 매개 값으로 주어진
문자 배열 c에 저장 , 실제로 읽은 문자 수 리턴

int

read(char[] c, int off, int len)

입력 스트림으로부터 len 개의 문자만큼 읽고
매개 값으로 주어진 문자배열 c[off]부터 len개까지 저장
실제로 읽은 문자 수인 len개 리턴

void

close()

사용한 시스템 자원 반납 후 입력 스트림 닫기

 

Writer

 문자 기반 출력 스트림의 최상위 클래스 , 추상 클래스

 

리턴타입

메소드

기능

void

write(int c)

출력 스트림으로 매개 값이 주어진 한 문자를 보냄

void

write(char [] c)

출력 스트림에 매개 값으로 주어진 문자 배열 c의 모든 문자를 보냄

void

write(char[] c, int off, int len)

출력 스트림에 매개 값으로 주어진
문자 배열 c[off]부터 len개까지의 문자를 보냄

void

write(String str)

출력 스트림에 매개 값으로 주어진 문자열을 보냄

void

write(String str, int off, int len)

출력 스트림에 매개 값으로 주어진 문자열
off순번부터 len개까지 문자를 보냄

void

flush()

버퍼에 잔류하는 모든 문자열 출력

void

close()

사용한 시스템 자원 반납 후 출력 스트림 닫기

 

File 클래스

 파일 시스템의 파일을 표현하는 클래스

 파일 크기, 파일 속성, 파일 이름 등의 정보와 파일 생성삭제 기능 제공

 

File 객체 생성

File file = new File(“파일 경로”);
File file = new File(“c:/data/test.txt”);

 

FileInputStream

 파일로부터 바이트 단위로 읽을 때 사용

 그림, 오디오, 비디오, 텍스트 파일 등 모든 종류의 파일 읽기 가능

 InputStream의 하위 클래스로 InputStream과 사용 방법 동일

 

FileInputStream 객체 생성

FileInputStream 객체가 생성될 때 파일과 직접 연결 됨
만약 파일이 존재하지 않으면 FileNotFoundException 이 발생하므로 예외처리 필수

 
FileInputStream fis = new FileInputStream(“c:/data/test.txt”);

 

new 기반스트림(외부자원); => 내가 연결하고자 하는 대상을 적어준다

 

FileOutputStream

 파일로부터 바이트 단위로 저장할 때 사용

 그림, 오디오, 비디오, 텍스트 파일 등 모든 종류의 데이터를 파일로 저장

 OutputStream의 하위 클래스로 OutputStream과 사용 방법 동일

 

FileOutputStream 객체 생성

FileOutputStream 객체가 생성될 때 파일과 직접 연결 됨
만약 파일이 존재하지 않으면 자동으로 생성하지만
이미 파일이 존재하는 경우 파일을 덮어쓰는 단점이 있음

FileOutputStream fos = new FileOutputStream(“c:/data/test.txt”);

만약 기존 파일에 이어서 계속 작성하고 싶다면 아래 예제처럼 객체 생성하면 된다
FileOutputStream fos = new FileOutputStream(“c:/data/test.txt”, true);

 

FileReader

 텍스트 파일을 문자 단위로 읽을 때 사용

 텍스트가 아닌 그림, 오디오, 비디오 등의 파일은 읽기 불가능 오직 텍스트만!

 Reader의 하위 클래스로 Reader와 사용 방법 동일

 

FileReader 객체 생성

FileReader 객체가 생성될 때 파일과 직접 연결 됨
만약 파일이 존재하지 않으면 FileNotFoundException이 발생하므로 예외처리 필수

 

FileReader fr = new FileReader(“c:/data/test.txt”);

FileReader fr = new FileReader(new File(“c:/data/test.txt”));

 

FileWriter

 텍스트 파일을 문자 단위로 저장 할 때 사용

 텍스트가 아닌 그림, 오디오, 비디오 등의 파일은 저장 불가능

 Writer의 하위 클래스로 Writer와 사용 방법 동일

 

FileWriter 객체 생성

FileWriter 객체가 생성될 때 파일과 직접 연결됨
만약 파일이 존재하지 않으면 자동으로 생성하지만
이미 파일이 존재하는 경우 파일을 덮어쓰는 단점이 있음

 

FileWriter fw = new FileWriter(“c:/data/test.txt”);

FileWriter fw = new FileWriter(“c:/data/test.txt”, true); //덮어쓰기


package com.io.fileTest;

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

public class TestFile {

	public static void main(String[] args) {
		
		//File 클래스
		File file = new File("p.txt");
		System.out.println("파일 객체 생성 완료 !");
		
		System.out.println("파일명 : " + file.getName());
		System.out.println("파일경로 : " + file.getPath());
		System.out.println("파일경로 : " + file.getAbsolutePath());
		System.out.println("파일용량 : " + file.length());
		//기본 경로가 자바 프로젝트로 잡혀있음을 알 수 있음.
		//getPath()는 기본경로가 생략된 상태로 출력되는것
		//파일을 아직 만든 것은 아니지만 경로를 지정해준것!
		//그래서 아직 file.getAbsolutePath() 에 출력된 경로로 이동 해 봤을때 파일이 만들어져있지 않음.
		
		try {
			boolean b = file.createNewFile();//try catch를 사용하지 않으면 빨간 줄 뜬다.
			System.out.println(b);
			//맨 처음 파일을 생성 할 때 true 출력
			//이미 파일이 만들어져 있는 상태에서 또 실행 시키면 false 출력
			//경로 확인해보면 p.txt 파일이 만들어져있음
			//Project Explorer F5 해도 파일 만들어진거 확인 가능
			
			//b = file.delete(); //파일 삭제되는거 확인 가능
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}

}

package com.io.part01_byteStream;

public class MTest {

	public static void main(String[] args) {
		TestByteStream f = new TestByteStream();
		//f.fileSave();
		f.fileOpen();
		
	}

}

 

package com.io.part01_byteStream;

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

public class TestByteStream {

	public void fileSave() {
		//FileOutputStream
		//클래스 이름을 보고 기반 스트림 , 바이트 단위의 출력 스트림 임을 알 수 있음
		
		FileOutputStream fout = null;
		
		try {
			fout = new FileOutputStream("sample.txt");//try catch 없으면 빨간 줄 뜬다.
			//     new 기반 스트림(외부자원);
			
			fout.write(97);
			//a가 적힌 sample.txt 파일이 생성된다!
			
			//fout.close(); 를 여기서 작성하지 않는 이유
			//fout.write(97);에서 Exception 발생시 catch문으로 넘어가기 때문에 finally 에서 처리한다.
			
			//---
			byte[] bar = {98, 99, 100, 101, 102, 10};
			fout.write(bar);
			// sample.txt 파일에 abcdef이 저장된다.
			//10은 뭘까? 개행문자
			
		}
		catch (FileNotFoundException e) {
			//fout = new FileOutputStream("sample/txt"); 의 	Exception 처리
			e.printStackTrace();
			
		}
		catch(IOException e) {
			//fout.write(97); 의 Exception 처리
			e.printStackTrace();
		}
		finally {
			try {
				fout.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}		
		
	}
	
	public void fileOpen() {
		//파일로부터 byte단위로 데이터를 읽어올 수 있는 스트림
		FileInputStream fin = null;
		
		try {
			fin = new FileInputStream("sample.txt");//try catch 없으면 빨간줄
			
			//방법 1
			/*
			//sample.txt 파일의 크기 받아오기
			int size = (int)new File("sample.txt").length();
			//sample.txt 크기만큼 배열 생성
			byte[] b = new byte[size];
			
			fin.read(b);
			
			for(int i=0; i < b.length; ++i ) {
				System.out.print(b[i] + " ");
				//97 98 99 100 101 102 10 출력된다 왜?
				//byte 단위로 파일을 읽어왔기 때문에
				//원본 파일에 적힌대로 알파벳으로 읽어오고 싶으면 char형으로 형변환 해주어야 한다.
				//영문자는 1바이트, 영문을 제외한 나머지는 2바이트
				 * 
				System.out.print((char)b[i] + " ");
				//97 a 98 b 99 c 100 d 101 e 102 f 10
				//char형으로 형변환하면 알파벳 그대로 잘 출력되는 것을 볼 수 있음
			}
			System.out.println();
			*/
			
			//방법2
			int val;
			//파일에서 문자를 읽어오다가, 파일의 끝을 만나면 -1을 반환받는다.
			//파일의 끝이 아닐 경우 ㄹㅇ 원본 파일의 바이트를 받아오고, 파일의 끝일 경우 -1를 받음
			//-> 파일의 끝임을 반환받은게 아니면 while 문 실행하는거임
			while((val = fin.read()) != -1) {
				System.out.print((char)val + " ");
				//a b c d e f 출력되고 종료된다.
				//sample.txt 파일에 가 라는 한글 한 문자 입력하고 종료 후 fileOpen 메소드 실행시켜서 파일을 읽어 올 경우
				//? ? 같이 문자가 깨져서 출력 되는데, 바이트 기반 스트림은 1바이트씩 읽어오는데 한글은 2바이트라서 이렇게 된다.
			}
			
		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		catch(IOException e) {
			//방법1에서
			//fin.read(b);을 사용하기위한 Exception 처리
			
			//방법2에서
			//val = fin.read()
			e.printStackTrace();
		}
		finally {
			try {
				fin.close();
			}catch(IOException e) {
				e.printStackTrace();
			}
			
		}
		
	}
	
}