본문 바로가기
자바(Java)

자바 중급13 - 자바IO

by codeyaki 2022. 1. 18.
반응형

해당 강의를 듣고 정리한 것입니다

https://programmers.co.kr/learn/courses/9

 

자바 중급

평가 5.0 17개의 평가 ★★★★★17 ★★★★0 ★★★0 ★★0 ★0 ds02168 2021.08.20 15:37 Yeonggwang 2021.06.28 01:48 강신우 2021.04.23 10:20 HyeonWoo Jeong 2021.04.08 17:12 이용준 2021.01.26 19:23 리뷰 더보기

programmers.co.kr


자바IO

: 입출력을 위한 인터페이스와 클래스들

  • 자바IO는 크게 byte단위 입출력과 문자 단위 입출력 클래스로 나뉨
    - byte단위 입출력 클래스는 모두 InputStream과 OutputStream이라는 추상 클래스를 상속 받음.
    - 문자(Char) 단위 입출력 클래스는 모두 Reader와 Writer라는 추상 클래스를 상속 받음.
  • 4가지 추상 클래스(InputStream, OutputStream, Reader, Writer)를 받아들이는 생성자가 있다면, 다양한 입출력 방법을 제공하는 클래스
  • 4가지 클래스를 받아들이는 생성자가 없다면, 어디로부터 입력받을 것인지, 어디에 쓸 것인지 나타내는 클래스.

장식대상 클래스 : 어디로부터, 어디에라는 대상을 지정할 수 있는 IO클래스.

  • 파일로부터 입력받고 쓰기 위한 클래스 : FileInputStream, FileOutputStream, FileReader, FileWriter
  • 배열로부터 입력받고 쓰기 위한 클래스 : ByteArrayInputStream, ByteArrayOutputStream, CharReader, CharWriter

장식하는 클래스 : 다양한 방식으로 입력하고, 출력하는 기능을 제공하는 클래스

  • DataInputStream, DataOutputStream 같은 클래스를 보면 다양한 데이터 형을 입력받고 출력함.
  • PrintWriter는 다양하게 한 줄 출력하는 print()메서드를 가지고 있음
  • BufferedReader는 한줄 입력받는 ReadLine() 메서드를 가짐

Byte단위 입출력

: 클래스의 이름이 InputStream이나 OutputStream으로 끝남.

  • 파일로부터 1byte씩 읽어들여 파일에 1byte씩 저장하는 프로그램을 작성
    - 파일로 부터 읽어오기 위한 객체 - FileInputStream
    - 파일에 쓸 수 있게 해주는 객체 - FileOutputStream
  • read() 메서드
    - byte를 리턴한다면 끝을 나타내는 값을 표현할 수가 없기 때문에, byte가 아닌 int를 리턴한다.
    - 음수의 경우 맨 좌측 비트가 1이 된다. 읽어 들일 것이 있다면 항상 양수를 리턴한다고 볼 수 있다!
  • FileInputStream과 FIleOutputStream을 이용하여, 1바이트씩 읽어 들여 1바이트씩 저장
    - read() 메서드가 리턴하는 타입은 정수, 정수 4바이트 중 마지막 바이트에 읽어 들인 1바이트를 저장.
    - read() 메서드는 더 이상 읽어 들일 것이 없을 때 -1을 리턴
import java.io.*;
public class ByteExam {
	public static void main(String[] args) {
		FileInputStream fi1 = null;
		FileOutputStream fo1 = null;
		
		try {
			fi1 = new FileInputStream("ByteExam.java");	//읽어들일 파일경로
			fo1 = new FileOutputStream("byte.txt");	//출력할 파일경로
			
			int readData = -1;
			while((readData = fi1.read()) != -1) {
				fo1.write(readData);
			}
					
		}catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				fo1.close();
				fi1.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
	}
	}
}

Byte 단위 입출력 심화

  • 수행 시간을 줄이기 위하여 512byte 단위로 읽어 들이고 파일에 512byte씩 저장하는 프로그램을 작성하기
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteExam2 {
	public static void main(String[] args) {
		FileInputStream fi1 = null;
		FileOutputStream fo1 = null;
		
		try {
			fi1 = new FileInputStream("ByteExam.java");	//읽어들일 파일경로
			fo1 = new FileOutputStream("byte.txt");	//출력할 파일경로
			
			int readCount = -1;
			byte[] buffer = new byte[512];
			while((readCount = fi1.read(buffer)) != -1) {
				fo1.write(buffer,0,readCount
						);
			}
					
		}catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				fo1.close();
				fi1.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
	}
	}
}
  • byte [] buffer = new byte [512]; 를 이용해 버퍼를 생성해주고 해당 버퍼를 넣어주면 된다.

시간 차이가 나는 이유?

기본단위가 512byte이기 때문에 1byte씩 입출력 시 먼저 512byte를 읽고 1byte만 가져온 뒤 나머지를 버리는 식으로 작동하기 때문에 시간이 더욱 걸린다.

 


다양한 타입의 출력(try-with-resources)

  • try-with-resources 사용 이유?
    - java io객체는 인스턴스를 만들고, 모두 사용하면 close() 메서드를 호출해야 함.
    - close()메서드를 사용자가 호출하지 않더라도, Exception이 발생하지 않는다면 자동으로 close()가 호출되게 함.

사용방법

  • try-catch블록에 추가로 ()를 사용해 try( IO객체 생성) { } catch {} 해주면 된다.
import java.io.DataOutputStream;
import java.io.FileOutputStream;

public class ByteExam3 {
	public static void main(String[] args) {
	
		try(DataOutputStream out = new DataOutputStream(new FileOutputStream("data.txt"));) {
			
			out.writeInt(100);	//4바이트
			out.writeBoolean(true);	//1바이트
			out.writeDouble(50.5);	//8바이트
		}catch (Exception e) {
			e.printStackTrace();
		}{
			
		}
	}
}

 


다양한 타입의 입력

  • data.dat로부터 값을 읽어 들여 화면에 출력하는 클래스
  • 다양한 타입의 데이터를 읽어낼 수 있는 DataInputStream
    - readInt() : 정수를 읽어 들이는 메서드
    - readBoolean() : boolean값을 읽어 들이는 메서드
    - readDouble() : double값을 읽어들이는 메서드
import java.io.DataInputStream;
import java.io.FileInputStream;

public class ByteExam4 {
	public static void main(String[] args) {
		try {
			DataInputStream in = new DataInputStream(new FileInputStream("data.txt"));
			int i = in.readInt();
			boolean b = in.readBoolean();
			double d = in.readDouble();
			System.out.println(i);
			System.out.println(b);
			System.out.println(d);
					
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
}
  • 파일에 저장된 순서대로 읽어 들여야 한다.
    - int, boolean, double 순서대로 저장하였기 때문에 읽어 들일 때도 같은 순서로 읽어야 한다.

Char단위 입출력(Console)

클래스 이름이 Reader, Writer로 끝이 남

  • Char단위 입출력 클래스를 이용해서 키보드로부터 한 줄 입력받아서 콘솔에 출력
    - System.in : 키보드를 의미(InputStream 타입)
    - BufferedReader : 한 줄씩 입력받기 위한 클래스 (InputStream을 입력받는 생성자가 없음, Reader객체만 가능)
    - System.in은 InputStream타입이므로 BufferedReader의 생성자에 바로 들어갈 수 없으므로 InputStreamReader클래스를 이용해야 함.
    - readLine()은 Exception이 발생할 수 있는 메서드이므로 try with catch 블록 안에서 사용해주어야 한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class CharIOExam1 {
	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line = null;
		try {
			line = br.readLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println(line);
	}
}

>>

입력 : hello!!

출력 : hello!!

 


char 단위 입출력(File)

:클래스 이름이 Reader나 Writer로 끝 이남!!

  • 파일에서 한 줄씩 입력받아서 파일에 출력
  • 한 줄 읽어 들이기 위해서 BufferedReader클래스 이용
    - BufferedReader클래스가 가지고 있는 readLine() 메서드가 한 줄씩 읽게 해 줌.
    - readLine() 메서드는 읽어낼 때 더 이상 읽어 들일 내용이 없을 때 null을 리턴
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;

public class CharIOExam2 {
	public static void main(String[] args) {
		
		try(	//try with resources
				BufferedReader br = new BufferedReader(new FileReader("CharIOExam2.java"));
				PrintWriter pw = new PrintWriter(new FileWriter("test.txt"));
				//데코레이터 패턴을 보여주기위한것. FileWriter를 사용하지 않아도 된다.
				) {
			
			String line = null;
			while((line= br.readLine()) != null) {
				pw.println(line);
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
}
반응형