반응형
해당 강의를 듣고 정리한 것입니다
https://programmers.co.kr/learn/courses/9
자바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();
}
}
}
반응형
'Language > Java' 카테고리의 다른 글
자바 중급15 - 스레드(쓰레드, Thread) 1 : 생성, 공유객체, 동기화블록(Snchronized) (0) | 2022.01.19 |
---|---|
자바 중급14 - 어노테이션(Annotation) (0) | 2022.01.19 |
자바 중급12 - time패키지 (0) | 2022.01.17 |
자바 중급11 - Date, Calendar클래스 (0) | 2022.01.17 |
자바 중급10 - Map (0) | 2022.01.17 |