본문 바로가기

Programming Language/JAVA

[JAVA] 파일 입출력

▶ 파일 입출력(InputStream,OutputStream,BufferedOutputStream,BufferedInputStream,DataOutputStream) 

 

 

 

 

 

파일 입출력
: 말그대로 파일을 입력하고 출력하는것 입니다.
(입력이란, 데이터를 내부로 받아들이는 것입니다.
출력이란, 데이터를 외부로 보내는것을 의미합니다.)

 

 

 



절대경로
: 컴퓨터 하드디스크의 이름부터 시작되는 경로 형식이다.
예) C:\Program Files\Java\jdk1.8.0_191\jre


상대경로
: 특정 폴더나 파일의 위치를 기준으로 하여 상대적으로 측정하는 경로이다.
예) ../../example.java
./example.java



java.io.File 클래스
: 파일 입출력과 관리를 하는 클래스이다.

아래그림에서 보시는바와 같이 "출력 스트림"과 "입력 스트림"으로 나뉘게됩니다.
-
스트림 : 입력과 출력을 하도록 이어주는 통로라고 생각하시면 됩니다.
-
입력 스트림(InputStream) : 데이터를 입력 할 수 있도록 입력된 데이터를 임시적으로 모아주는 통로
-
출력 스트림(OutputStream) : 데이터를 출력할 수 있도록 출력할 데이터를 임시적으로 모아주는 통로

 


 

 

 

 

 

 

 


 

◎ FileOutputStream

 

 

 

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

public class Test {

	public static void main(String[] args) throws FileNotFoundException {
		File filePath = new File("D:\\Test\\aaa.txt");
		FileOutputStream fos = new FileOutputStream(filePath);
		System.out.println("aaa.txt 생성완료");
		
	}

}

File클래스의 객체를 생성할때 인자값으로 경로를 넣어주고 마지막에 생성할 파일명과 확장자명을 입력해주면
FileOutputStream을 통해 해당 경로를 설정한 변수를 인자값으로 넣어주면 됩니다.
사진과 같이 파일이 생성된걸 확인하실수있습니다.

 

 

 

 

 

 

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

public class Test {

	public static void main(String[] args) throws IOException {
		File filePath = new File("D:\\Test\\aaa.txt");
		FileOutputStream fos = new FileOutputStream(filePath);
		
		fos.write(97);
		fos.write('A');
		
		
	}

}

fos라는 FileOutputStream클래스 객체를 생성한 인스턴스명을 사용해서 write메소드()를 호출해줍니다.
인자값으로 97을 넣어주면 소문자a가 해당 aaa.txt파일에 입력됩니다. (아스키코드표 참고)
대문자A는 그냥 문자로 넣어주었습니다.

 

 

 

 

 

 

 

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Test {

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		File file =  new File("D:\\Test\\bbb.txt");
		FileOutputStream fos = new FileOutputStream(file);
		String str;
		
		System.out.println("파일로 저장할 값 입력:");
		str = sc.next();
		fos.write(str.getBytes());
	}

}

이번에는 Scanner클래스를 통해서 사용자로부터 콘솔창에서 입력받은 문자를 bbb.txt 메모장에
write()메소드를 호출해서 입력받은 문자를 Byte형식으로 인자값으로 전달했습니다.
사진을 보시면 bbb.txt파일에 Hello가 저장된걸 확인할수있습니다.

 

 

 

 


 

 

 

◎ FileInputStream 

 

 

 

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

public class Test {

	public static void main(String[] args) throws IOException, InterruptedException {
		File filePath = new File("D:\\Test\\bbb.txt");
	
		FileInputStream fis = new FileInputStream(filePath);
		while(true) {
			int res = fis.read(); 
			if(res<0) {
				break;
			}else {
				System.out.print((char)res);
			}
		}
	}
}

이번에는 반대로 FileInputStream에 대해 알아보겠습니다.

FileOutputStream에서 bbb.txt파일을 생성하면서 Hello문구를 넣고 저장해주었습니다.
이번에는 FileInputStream으로 bbb.txt파일을 불러와서 이클립스 콘솔창에서 저장된 값을 출력해주는 실습입니다.
FileInputStream을 통해 fis인스턴스를 생성해주고 반복문을 이용해서 read()메소드를 호출해서 bbb.txt파일에 들어있는
데어터를 읽어와서 int데이터 타입의 변수 res에 하나씩 저장해줍니다.
받아온 값이 음수일경우 break키워드를 사용해서 반복문을 나가게되고, 그렇지않다면 하나씩 출력해주는데 int형으로 가져왔기에 (char) 형변환을 통해 콘솔창에 출력해줍니다.

 

 

 

 


 

 

 BufferedOutputStreamBufferedInputStream

: 스트림의 입출력 효율을 높이기 위해 버퍼를 사용하는 보조스트림 입니다.
한 바이트씩 입출력하는 것보다 버퍼(바이트배열)을 이용합니다.
대부분의 입출력 작업에 사용됩니다.

 

 

 

 

 

 

 

◎ BufferedOutputStream

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {

	public static void main(String[] args) throws IOException, InterruptedException {
		FileOutputStream fos = new FileOutputStream("D:\\Test\\ccc.txt");
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		for(int i='1'; i<='9'; i++) {
			bos.write(i);
		}
		//bos.close();
	}
}

BufferedOutputStream클래스의 인스턴스를 생성해줄때 인자값으로 ccc.txt파일을 해당 경로에 생성해줍니다.
그리고 1~9까지의 숫자를 ccc.txt파일에 데이터로 저장해주려합니다.
BufferedOutputStream를 이용하면 버퍼를 이용하기때문에 입출력 효율성이 높아집니다.
그리고 마지막 //주석처리한 bos.close()는 해당 소스가 없을경우, 데이터가 저장되지않습니다.
bos를 꼭 종료시켜줘야 데이터가 정상적으로 저장되는것을 확인할 수 있습니다.

 

 

 

 

◎ BufferedInputStream

import java.io.*;

public class Test {

	public static void main(String[] args) throws IOException {
		File f = new File("D:\\Test\\abc.jpg");
		FileInputStream fis = new FileInputStream(f);
		BufferedInputStream bis = new BufferedInputStream(fis);
		int fsize = (int)f.length();
		
		System.out.println("fsize: "+fsize);
		
		byte b[] = new byte[fsize];
		bis.read(b);
		bis.close();
		fis.close();
		FileOutputStream fos = new FileOutputStream("D:\\Test0101\\test.jpg");
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		bos.write(b);
		bos.flush();
		bos.close();
		fos.close();
		
	}

}

 

이번에는 BufferedInputStream에 대해 알아보겠습니다.
우선 D:\\Test\\abc.jpg의 경로에있는 abc.jpg를 읽어와서 fsize를 알아본후, 콘솔창에 출력해줍니다.
byte타입의 배열에 하나씩 값을 넣어서 read해주고 D:\\Test0101\\test.jpg 경로로 test.jpg로 저장해주는
BufferedOutputStream을 사용해서 값을 저장해주었습니다.

 

 


 

 

 

DataInputStreamDataOutputStream
: 데이터를 읽고 쓰는데 byte단위가 아닌 8가지 자료형으로 사용된다.
각 자료형의 크기가 다르므로, 출력한 데이터를 읽어 올 때는 출력했을때의 순서를 염두에 두어야 합니다.

 

 

 

 

◎ DataOutputStream

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test{

	public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("D:\\Test\\aaa.txt");
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		DataOutputStream dos = new DataOutputStream(bos);
		
		dos.writeUTF("김개똥");
		dos.writeInt(100);
		dos.writeInt(80);
		
		dos.flush();
		dos.close();
	}

}

DataOutputStream는 다른거와 차이점은 8가지 자료형을 가능하다는 점이다.
BufferedOutputStream 의 bos인스턴스를 DataOutputStream에 인자값으로 넣어주고 writeUTF()메소드를 호출해서
저장할 데이터를 하나씩 넣어줍니다. 메소드는 자료형별로 있기에 장점이있습니다.
하지만, 다음에 예제에서 보시면 단점이 있습니다.

 

 

 

 

 

 

 

◎ DataInputStream

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Test {

	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("D:\\Test\\aaa.txt");
		BufferedInputStream bis = new BufferedInputStream(fis);
		DataInputStream dis = new DataInputStream(bis);

		String name = dis.readUTF();
		int kor = dis.readInt();
		int eng = dis.readInt();
		System.out.println(name + "님의 성적 : " + (kor + eng));
	}

}

DataInputStream으로 aaa.txt에 저장한 "김개똥"과 "100"과 "80"을 콘솔창으로 출력해보려합니다.
즉, DataInputStream을 통해 값을 뺴와야하는데 이때 중요한건 입력한 값 순서대로 빼와야합니다.
보시면 name과 kor와 eng 순서로 출력해왔고 메시지를 출력해주었습니다.
단점은 순서를 기억하고 염두에 두어야한다는 점입니다.