국비교육(22-23)

22일차(2)/java(31) : Input, Output(3)

서리/Seori 2022. 11. 4. 21:43

 

MainClass15

- 파일시스템에 접근해 이미지파일 복사하기. read()

package test.main;

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

public class MainClass15 {
	public static void main(String[] args) {
		
		//필요한 참조값을 담을 지역변수를 미리 만든다.
		FileInputStream fis=null;
		FileOutputStream fos=null;
		try {
			//파일에서 byte를 읽어낼 객체
			fis=new FileInputStream("c:/acorn202210/myFolder/bottle.png");
			//파일에 byte를 출력할 객체
			fos=new FileOutputStream("c:/acorn202210/myFolder/copied.png");
			while(true) {
				//byte 알갱이 하나씩 읽어들인다
				int data=fis.read();
				//만일 더이상 읽을 byte가 없다면
				if(data==-1) {
					break; //반복문 탈출
				}
				System.out.println(data);
				//읽은 byte 알갱이 하나를 출력하기
				fos.write(data);
				fos.flush();
			}
		} catch (Exception e) {			
			e.printStackTrace();
		} finally {
			try {
				if(fos!=null)fos.close();
				if(fis!=null)fis.close();	
				} catch (IOException e) {}			
		}		
	}
}

 

 

- 한개의 이미지, 총 68043개의 바이트를 읽어 복사할 예정!

 


FileInputStream : 파일 객체에서 바이트 알갱이를 읽어올 수 있는 객체
FileOutputStream : 읽어낸 바이트 알갱이를 파일에다가 출력하는 객체


- 생성자의 인자는 파일 객체(읽어올 파일)를 넣어줘도되고 경로를 문자열로 적어줘도 된다.

 

- exception이 발생해서 try블록으로 묶어야 함!

 

- 파일(이미지)를 읽고 복사해서 원하는 폴더에 출력하기

- 지역변수는 try 문 밖에서 생성해두고, try문 안에서 값 대입!

 

- byte라는 것은 어떤 정수라고 생각하면 된다.

- 일반적으로 0~255 범위 또는 -127~128 범위이다. 총 255가지이기만 하면된다.

 

 

- fis(FileInputStream 타입)에서 읽어올 수 있는 메소드들!

 

- byte를 하나씩 읽어오는 방법과

  byte배열을 이용하는 방법이 있다.(한번에 배열 방의 개수만큼 읽어낸다)

 

- fos도 하나씩 읽어오기 / 배열로 출력하기 두가지로 가능!

 

- run 하면 콘솔창에 수많은 byte알갱이들이 숫자(코드)로 나타나고, 폴더에 copied 파일도 복사돼 있다.

 

 

 

- FileInputStream의 read란 객체를 활용해 읽어오고

 FileOutputStream의 write, flush란 객체를 활용해 출력하는 것!

 

- java에 만들어져 있는 기능을 다양한 클래스와 메소드를 활용해서 읽어들이는 것이다.

 

- 파일시스템에 대한 지식이 없어도 inputstream이라는 객체를 사용해 파일시스템 접근이 가능.

(java가 고급 언어이기 때문에. 그런 세세한 내용까지 몰라도 활용할 수 있다.)

 


 

- .read() 는 하나하나 읽어오기 때문에 파일 크기가 큰 경우 너무 오래 걸린다.

- 바이트 배열[]을 전달하는 방식 사용해보기!

 

 

MainClass16

- 파일시스템에 접근해 이미지파일 복사하기. read(byte[])

package test.main;

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

public class MainClass16 {
	public static void main(String[] args) {
		
		//필요한 참조값을 담을 지역변수를 미리 만든다.
		FileInputStream fis=null;
		FileOutputStream fos=null;
		try {
			//파일에서 byte를 읽어낼 객체
			fis=new FileInputStream("c:/acorn202210/myFolder/bottle.png");
			//파일에 byte를 출력할 객체
			fos=new FileOutputStream("c:/acorn202210/myFolder/copied2.png");
			
			//byte[] 객체를 미리 준비한다.
			byte[] buffer = new byte[1024]; //한번에 1kilo byte씩 읽어낼 수 있는 byte 배열
			
			while(true) {
				//byte[] 배열을 메소드의 인자로 전달해서 읽어들이고 몇개를 읽어들였는지 리턴받는다.
				int readedByte=fis.read(buffer);
				if(readedByte==-1) {
					break;
				}
				//byte[] 배열의 0번 방에서부터 읽은 만큼만 출력하기.
				fos.write(buffer, 0, readedByte);
				fos.flush();
			}
		} catch (Exception e) {			
			e.printStackTrace();
		} finally {
			try {
				if(fos!=null)fos.close();
				if(fis!=null)fis.close();	
				} catch (IOException e) {}			
		}		
	}
}

 

- byte[] 바이트 배열을 받는 생성자 사용!

- 읽어온 알갱이 숫자들을 바이트 배열의 방 하나하나에 넣는다.

 

- 리턴값은 int이다. 전체 몇개를 읽었는지도 리턴해준다.

- read(); 설명 :  Returns: the total number of bytes read into the buffer, or -1 if there is no more data because the end of the file has been reached.

→ byte 배열(묶음) 으로 한번에 n개씩 퍼내다가 나중에는 보다 작은 숫자를 리턴하고, 마지막에는 -1을 리턴할 것.

 

byte[] buffer = new byte[1024]; 

- 한번에 1kilo byte씩 읽어낼 수 있는 바이트 배열. 한번에 1024개씩 읽어내도록 지시!

 

 

 

- run하면 copied2가 조금 더 빨리 복사된다.

- byte를 묶음으로 해서 한번에 1024개씩 읽어오는 것이기 때문에!

 


 


- byte[] 배열이 있다는 것은 공간이 1024개 있다는 것. 만들어진 시점에는 0이 들어가 있다.
- 디버그모드에서 보면 32번(id) 사물함에 배열 객체가 있다. 열어보면 0이 들어있다.

 

- 0이었던 방에 숫자들이 대입된다. 첫 1024개 묶음을 읽어온 것!

 


fos.write(buffer, 0, readedByte);
- 0번 방에서부터 1024개를 읽어와달라는 요청!

- 디버그를 쭉 돌려보면 1024개씩 각각의 방에 숫자가 반복적으로 채워지는 것을 볼 수 있다.