본문 바로가기
JAVA

[파일 입출력] TXT & 이미지형식 (+Wrapper Class)

by amoomar 2022. 1. 14.
반응형

FileInputScream(fis)와 FileOutputScream(fos), FileReaderFileWriter을 활용하여 실습과 예제를 통해 txt형식과 이미지형식의 파일 입출력에 대한 수업 내용을 포스팅하였다. 추가로 이전에 다루지 않았던 Wrapper Class에 대해서도 간략한 정리가 담겼다!

 

 


 

1. fis(File Input Scream) & fos(File Output Scream)

1) 기본이론

자바에서 다루는 파일 입출력이란 console없이 바로 OS(운영체제)와 소통하는 것이라고 할 수 있다.

 

파일은 사진, 동영상, 음성, 문서, 텍스트문서 등등 다양한 형태와 그에 맞는 형식으로 존재한다.

 

파일 입출력에서 다루는 작업의 종류는 파일이 존재하는 경로복사를 통해 해당 파일로 접근하기, 파일 내용 불러오기, 파일 내용 작성 or 수정하기, 이어쓰기가 있다.

 

fis는 Input개념으로 파일을 Java로 불러오는 기능을 하며, 반대로 fos는 Output의 개념으로 작성, 수정, 이어쓰기의 기능이 있다. 두 클래스는 공통적으로 다음과 같은 기능도 가지고 있는데, 지정한 경로에 입력한 파일이름이 존재하지 않는다면 입력한 파일명으로 새로 생성하고, 존재한다면 덮어쓴다(잘못된 명령으로 데이터들을 전체 덮어쓰기 하지 않도록 주의 필요,,)

 

*File경로관리

: file의 경로를 여러번 사용해야하는 경우 번거로움을 줄이기 위해서 아래와같이 두가지 방법을 통해 파일의 경로를 관리한다.

  1. File의 객체화 
  2. File file = new File("C:\\JAVA1_1800_HJH\\resource\\test.txt"); //사용시 FileInputScream fis = new FileInputScream(file); FileOutputScream fos = new FileOutputScream(file);
  3. 변수선언
    // 상수화를 통해 경로의 수정을 방지한다.
    // 파일을 여러개 생성해야 하는 경우에 유용하게 쓰인다.
    final String path1 = "C:\\JAVA1_1800_HJH\\resource\\test";
    final String path2 = ".txt";​
    
    int i =1; //for문 사용을 통해 원하는 개수의 폴더를 한 번에 생성할 수 있다!
    FileOutputStream fos = new FileOutputStream(path1 + i + path2, true);//true는 이어쓰기표시

 

*fis의 주요메서드

  • read( ); : 지정한 파일의 내용을 불러오는 메서드이다. 배열리스트의 전체내용 출력에서 사용되는 이터레이터와 유사한 성질을 가지고 있다. 파일의 데이터를 한칸씩 끊어서 읽어내며, 읽은 칸은 바로 잊기때문에 while문을 사용하여 지정한 범위가지의 내용을 읽어들이고, 읽은 내용을 변수에 저장하는 방식으로 사용된다. 이때 파일의 끝에 닿으면 -1을 반환하므로 while의 반복 범위는 읽은 데이터가 -1이 아닐때까지 이다. 다양한 인자로 오버로딩 되어있다.
try {
	FileInputStream fis = new FileInputStream("C:\\JAVA1_1800_HJH\\resource\\test.txt");
			
	//fis.read()가 읽자마자 그걸 int data로 저장하고, 그걸 출력
	int data; //fis는 숫자로 구성된 데이터이므로!
	while((data=fis.read()) != -1) { 
				
		// 아스키코드로 출력되니 형변환하여 출력되도록한다.
		System.out.print((char)data); 
		}
			
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {
		System.out.println("로깅 : fis객체로 읽어오기 완료");
	}

*fos의 주요메서드

  • write( ); : 괄호 안에 입력된 내용이 지정한 파일의 내용으로 입력된다. 이또한 다양한 인자로 오버로딩되어있다.
  • flush( ); : 오류방지(쓰레기값방지)를 목적으로 사용된다. 해당 스트림을 비우겠다는 의미를 담는다.
  • close( ); : 오류방지(쓰레기값방지)를 목적으로 사용된다. 해당 스트림을 닫겠다는 의미를 담는다.
    try {
    	FileOutputStream fos = new FileOutputStream("C:\\JAVA1_1800_HJH\\resource\\test.txt");
    		
    	fos.write(65);//인자가 int라서 -> 아스키코드"A"입력되었음을 알 것
    			
    	//★쓰레기값 방지 필수★
    	//나중에 오류 생길텐데 그때 발견하면 늦는당
    	fos.flush(); //해당 스트림을 비우고
    	fos.close(); //닫기
    			
    } catch (FileNotFoundException e) {
    	// TODO Auto-generated catch block
    	e.printStackTrace();
    } catch (IOException e) {
    	// TODO Auto-generated catch block
    	e.printStackTrace();
    } finally {
    	System.out.println("로깅 : fos객체로 파일 작성하기 완료");
    }​

 

 

 


 

2) txt

: 위의 내용을 활용하여 txt형식의 파일을 복사해보자.

read( )와 write( )의 인자로 int 타입이 오버로딩 된 것을 사용하였다.

package class01;

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

public class Test04 {

	public static void main(String[] args) {
		
		int data=0; //원본내용
		 //원본복사 : 개수가 정해지지않은 여러개의 정수
		ArrayList <Integer> paste = new ArrayList<Integer>(); 
		String path1 = "C:\\JAVA1_1800_HJH\\resource\\test";
		String path2 = ".txt";
		
		// 1. 원본파일 접근하기
		File file = new File( path1 + path2 ); //경로 확인
		
		try { //파일 객체 생성
			file.createNewFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		// 2. 원본파일 불러오기
		try {
			FileInputStream fis = new FileInputStream(file);
			
			//2-2. int data를 이용하여 fis.read저장(fis는 int이므로)
			//	무한루트 방지를 위해 -1이 아닐때까지만 data를 읽으라고 명령
			//	data에 저장된 파일내용은 .txt이므로 형변환(char:한글자씩읽음)
			//	paste.add(data);를 통해 배열리스트에 원본내용 저장
			//	오류 방지를 위해 cath (IOException e)생성되도록 함
			
			while((data=fis.read()) != -1) {
				System.out.print((char)data);
				paste.add(data);
			}
			System.out.println();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("원본 내용");
		}
		
		// 3. 복사본 생성
		try {
			FileOutputStream fos = new FileOutputStream(path1+" - 복사본 "+path2);
			
			//3-1. 복사본 내용 생성하기
			//	 paste배열리스트(복사된 내용)를 연결하여 줄줄이 출력 
			//	 쓰레기값 방지를 위해 비우고(flush), 닫기(close)
			//	 오류 방지를 위해 catch (IOException e)생성되도록 함
			
			for(int i=0; i<paste.size(); i++) {
				fos.write(paste.get(i));				
			}
			fos.flush();
			fos.close();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
}

지정한 경로로 정상적인 작동 확인!
파일 내용 확인 !

 


 

3) 이미지(jpg, png...)

: read( )와 write( )인자가 byte [ ] (바이트 배열 타입)인 오버로딩을 활용했다. 이미지의 경우는 파일의 내용이 아스키코드로 전환이 어려워 int자료형으로는 사용이 어렵기 때문에 해당 방식을 활용한다.

package class02;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Test01 {

	public static void main(String[] args) {
		// C:\\JAVA1_1800_HJH\\resource\\image.jpg

		try {
			FileInputStream fis = new FileInputStream("C:\\JAVA1_1800_HJH\\resource\\image.jpg");
			FileOutputStream fos = new FileOutputStream("C:\\JAVA1_1800_HJH\\resource\\image - 복사본.jpg");

			//배열길이 지정해야하므로 넉넉한 입력
			byte[] buff = new byte[3000]; 
			// byte[] 를 인자로 받는 read메서드를 오버로드
			int lenght;
			while((lenght=fis.read(buff)) != -1) { 
				//buff공간에서 0데이터를 lenght만큼 write할게
				fos.write(buff, 0, lenght); 
			}

			fos.flush(); //비우고
			fos.close(); //닫기

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("사진복사 실습완료");
		}


	}
}

지정한 경로로 정상적인 복사 확인
파일 내용 확인

 


 

4) 예제

byte[ ] 을 활용하여 txt형식 파일 복사본 만들기 !

package class02;

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

public class Test02 {

	public static void main(String[] args) {
		//  C:\\JAVA1_1800_HJH\\resource\\test2.txt
		
		try {
			FileInputStream fis = new FileInputStream("C:\\JAVA1_1800_HJH\\resource\\test2.txt");
			FileOutputStream fos = new FileOutputStream("C:\\JAVA1_1800_HJH\\resource\\test2 - 복사본 .txt");
		
			byte [] buff = new byte[3000];
			int lenght;
			while((lenght=fis.read(buff)) != -1) {
				fos.write(buff, 0, lenght);
			}
			
			fos.flush();
			fos.close();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("txt파일 복사 예제 완료!");
		}
		
		
	}
}

 

지정한 경로로 정상적인 복사 확인
파일 내용 확인

 


 

2. FileReader & FileWriter

1) 예제를 통한 이해

(1) test.txt파일에 값을 저장, (2) 해당값을 console에서 맞추면 (3) result.txt파일에 결과 저장하기

package class02;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.Scanner;

public class Test03 {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		int user; //콘솔에서의 입력
		int cnt=0; // 입력 회수
		int num=0; //int로 형변환된 String
		ArrayList <Integer> al = new ArrayList <Integer>(); //길이를 모르니까!
		//아스키코드 : 48~57(0~9)
		al.add(55);
		al.add(51);

		// 1. 100이하의 정수를 저장한 파일 생성   
		try {
			FileWriter fw = new FileWriter("C:\\NewFile\\NewResouse\\test.txt");

			//리스트의 값을 메모장에 저장하는 작업
			for(int i=0; i<al.size(); i++) {         
				fw.write(al.get(i));
			}

			//쓰레기값 생성 방지
			fw.flush(); //비우기
			fw.close(); //닫기
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("정답파일 생성 완료");
		}
		System.out.println();


		// 2. 1번 불러오기
		try {
			FileReader fr = new FileReader("C:\\NewFile\\NewResouse\\test.txt");

			char[] cbuff=new char[1000];
			int len=fr.read(cbuff);
			String str="";
			for(int i=0;i<len;i++) {
				str += cbuff[i]; //char[]을 String으로 전환해서 변수에 담기
			}
			// System.out.println(str); char[]이 담긴 문자열 출력
			num=Integer.parseInt(str); //문자열 정수로 형변환
			// System.out.println(num); //형변환된 String 출력

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 3. 정답결과 result에 담기 + 입력예외처리
		while(true) {//입력을 위한 반복
			
			try {			
				System.out.println(">>");
				user = sc.nextInt();
				cnt++; //자료형이 올바른 입력만 cnt++
				
				if(user==num) {//입력이 test의 내용과 같으면 종료
					break;
				}
			}catch(InputMismatchException e) {
				sc.nextLine();
				System.out.println("정수만 입력하세요");
			}
			catch(Exception e) {
				e.printStackTrace();
			}

		}
		//while이 종료되면 ! result에 내용을 입력하도록
		try {

			FileWriter fw = new FileWriter("C:\\NewFile\\NewResouse\\result.txt");
			PrintWriter pw = new PrintWriter(fw);
			pw.print("대장님, " + cnt + "번만에 맞추셨습니다 :D");

			pw.flush();
			pw.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("result.txt파일을 조회해보세요!");
		}

	}
}

[출력화면 : -> 입력]

정답파일 생성 완료

>>
33
>>
2
>>

정수만 입력하세요
>>
7.5
정수만 입력하세요
>>
73
result.txt파일을 조회해보세요!


 

[파일조회]

파일 내용 확인

 


3. Wrapper Class : 래퍼클래스

1) java의 데이터타입

  1. 원시(기본)타입의 종류 : int, char, byte, short, float, double, long, boolean
  2. 참조타입의 종류 : class, interface등 (Wrapper도 여기 포함!)

래퍼클래스기본 자료타입(primitive type)을 객체로 다루기 위해서 사용하는 클래스이다. 종류로는 Integer, Character, Byte, Short, Float, Double, Long, Boolean등이 있다.

 

//잘못된 Wrapper class의 사용
Integer i1 = new Integer();
Double d = new Double();

//올바른 Wrapper class의 사용
String str = "1234";
int i = Integer.parseInt(str);

//형변환시 계산도 정상적으로 작동!
System.out.println(i+1); //[1235출력]

 

 


 

2) 박싱 & 언박싱

 

박싱 : 원시타입을 참조타입으로 변환하는 것

Integer num = new Integer(100);

 

언박싱 : 참조타입을 원시타입으로 변환하는 것

int n = num.intValue();

 


 

3) 오토박싱 & 오토언박싱

 

1.5버전 이상에서는 컴파일러에 의해 기본타입이 래퍼타입으로 자동변환되므로 오토박싱과 오토 언박싱이 사용 가능하다.

 

오토박싱 초기화 없이 원시타입을 참조타입으로 변환하는 것

Character ch = 'A';

 

오토언박싱 : 초기화 없이 참조타입을 원시타입으로 변환하는 것

char c = ch;

 

 

 


 

반응형