프로그래머스 자바 중급 강의를 학습 목적으로 정리하여 포스팅합니다.
1. 자바IO
입출력을 위한 인터페이스와 클래스들
자바 I(Input)O(Output)는 byte 단위 입출력 클래스와 문자 단위 입출력 클래스로 나뉜다.
- byte 단위 입출력 클래스는 모두 InputStream과 OutputStream이라는 추상클래스를 상속받아 만들어진다.
- char 단위 입출력 클래스는 모두 Reader와 Writer라는 추상클래스를 상속받아 만들어진다.
4가지 추상클래스(InputStream, OutputStream, Reader, Writer)를 받아들이는 생성자가 있다면 다양한 입출력 방법을 제공하는 클래스이다.
4가지 추상클래스를 받아들이는 생성자가 없다면 어디로부터 입력받을 것인지, 어디에 쓸 것인지를 나타내는 클래스이다.
- 파일로부터 입력받고 쓰기 위한 클래스 : FileInputStream, FileOutputStream, FileReader, FileWriter
- 배열로부터 입력받고 쓰기 위한 클래스 : ByteArrayInputStream, ByteArrayOutputStream, CharReader, CharWriter
해당 클래스들은 어디로부터, 어디에라는 대상을 지정할 수 있는 IO 클래스이다.
이런 클래스를 장식 대상 클래스라고 한다.
- DataInputStream, DataOutputStream 같은 클래스를 보면 다양한 데이터형을 입력받고 출력한다,
- PrintWriter는 다양하게 한 줄 출력하는 println() 메소드를 가지고 있다.
- BufferedReader는 한 줄 입력받는 readLine() 메소드를 가진다.
이런 클래스들은 다양한 방식으로 입력하고 출력하는 기능을 제공한다.
이런 클래스를 장식하는 클래스라고 한다.
자바 IO는 데코레이터 패턴이다. 데코레이터 패턴이란 하나의 클래스를 장식하는 것처럼 생성자에 감싸서 새로운 기능을 계속 추가할 수 있도록 클래스를 만드는 방식
2. Byte 단위 입출력
byte 단위 입출력 클래스는 클래스의 이름이 InputStream이나 OutputStream으로 끝난다.
파일로부터 1byte씩 읽어들여 파일에 1byte씩 저장하는 프로그램을 작성한다.
- FileInputStream : 파일로부터 읽어오기 위한 객체
- FileOutputStream : 파일에 쓸 수 있게 해주는 객체
read() 메소드가 byte를 리턴한다면 끝을 나타내는 값을 표현할 수가 없기 때문에 byte가 아닌 int를 리턴한다.
음수의 경우 맨 좌측 비트가 1이 된다. 읽어들일 것이 있다면 항상 양수를 리턴한다고 볼 수 있다.
read() 메소드가 리턴하는 타입은 정수인데 정수 4byte 중 마지막 byte에 읽어들인 1byte를 저장한다.
read() 메소드는 더 이상 읽어들일 것이 없을 때 -1을 리턴한다.
public class ByteIOExam1 {
public static void main(String[] args){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("src/javaIO/exam/ByteExam1.java");
fos = new FileOutputStream("byte.txt");
int readData = -1;
while((readData = fis.read())!= -1){
fos.write(readData);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- IO에 모든 객체는 인스턴스화한 후에 꼭 닫아주어야한다. close() 해주는 것을 잊지말자!
3. Byte 단위 입출력 심화
파일로부터 512byte씩 읽어들여 파일에 512byte씩 저장하는 프로그램
속도면에서 훨씬 더 빠르다.
public class ByteIOExam1 {
public static void main(String[] args){
//메소드가 시작된 시간을 구하기 위함
long startTime = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("src/javaIO/exam/ByteExam1.java");
fos = new FileOutputStream("byte.txt");
int readCount = -1;
// 변경된 부분
byte[] buffer = new byte[512];
while((readCount = fis.read(buffer))!= -1){
fos.write(buffer,0,readCount);
}
//
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//메소드가 끝났을때 시간을 구하기 위함.
// 현재 시간을 long 타입으로 반환
long endTime = System.currentTimeMillis();
//메소드를 수행하는데 걸린 시간을 구할 수 있음.
System.out.println(endTime-startTime);
}
}
4. 다양한 타입의 출력
java io 객체는 인스턴스를 만들고 모두 사용하면 close() 메소드를 호출해야 한다.
close() 메소드를 사용자가 호출하지 않더라도 Exception이 발생하지 않았다면 자동으로 close()가 되게 할 수 있는 방법이 try-with-resources 블록이다.
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);
out.writeBoolean(true);
out.writeDouble(50.5);
}catch (Exception e) {
e.printStackTrace();
}
}
}
다양한 타입으로 저장할 수 있는 DataOutputStream
- writeInt() : 정수값으로 저장
- writeBoolean() : boolean값으로 저장
- writeDouble() : double값으로 저장
5. 다양한 타입의 입력
파일로부터 값을 읽어들여 화면에 출력하는 DataInputStream
import java.io.DataInputStream;
import java.io.FileInputStream;
public class ByteIOExam4 {
public static void main(String[] args) {
try(
DataInputStream out = new DataInputStream(new FileInputStream("data.dat"));
){
int i = out.readInt();
boolean b = out.readBoolean();
double d = out.readDouble();
System.out.println(i);
System.out.println(b);
System.out.println(d);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
파일에 저장된 순서와 같게 읽어들여야 한다.
- readInt() : 정수를 읽어들이는 메소드
- readBoolean() : boolean값을 읽어들이는 메소드
- readDouble() : double값을 읽어들이는 메소드
6. Char 단위 입출력(Console)
char 단위 입출력 클래스는 클래스 이름이 Reader나 Writer로 끝난다.
- System.in : 키보드를 의미(InputStream)
- BufferedReader : 한 줄씩 입력 받기 위한 클래스
BufferedReader 클래스의 생성자는 InputStream을 입력받는 생성자가 없다.
System.in은 InputStream 타입이므로 BufferReader의 생성자에 바로 들어갈 수 없으므로 InputStreamReader 클래스를 이용해야 한다.
데코레이터 패턴
객체에 추가적인 요건(기능)을 동적으로 첨가하는 방식
서브클래스를 만드는 것을 통해 기능을 유연하게 확장할 수 있는 방법 제공
ex) BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class CharIOExam01 {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//키보드로 입력받은 문자열을 저장하기 위해 line변수를 선언
String line = null;
try {
line = br.readLine()
} catch (IOException e) {
e.printStackTrace();
}
//콘솔에 출력
System.out.println(line);
}
}
7. Char 단위 입출력(File)
파일에서 한 줄씩 입력받아서 파일에 출력하는 코드
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class CharIOExam02 {
public static void main(String[] args) {
BufferedReader br = null;
PrintWriter pw = null;
try{
br = new BufferedReader(new FileReader("src/javaIO/exam/CharIOExam02.java"));
// 데코레이터패턴으로 작성하지 않아도 됨
pw = new PrintWriter(new FileWriter("test.txt"));
String line = null;
while((line = br.readLine())!= null){
pw.println(line);
}
}catch(Exception e){
e.printStackTrace();
}finally {
pw.close();
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileReader 클래스 : 파일을 읽음
BufferedReader 클래스 : 파일을 한 줄씩 읽음
- BufferedReader 클래스가 가지고 있는 readLine() 메소드가 한 줄씩 읽게 해준다.
- readLine() 메소드는 읽어낼 때 더 이상 읽어 들일 내용이 없으면 null을 리턴한다.
FileWriter 클래스 : 파일에 씀
PrintWriter 클래스 : 출력
'JAVA > [프로그래머스] 자바 강의' 카테고리의 다른 글
[프로그래머스] 자바 중급 강의 part7. 쓰레드 (0) | 2023.02.13 |
---|---|
[프로그래머스] 자바 중급 강의 part6. 어노테이션 (0) | 2023.02.08 |
[프로그래머스] 자바 중급 강의 part4. 날짜와 시간 (1) | 2023.02.01 |
[프로그래머스] 자바 중급 강의 part3. java.util 패키지 (1) | 2023.02.01 |
[프로그래머스] 자바 중급 강의 part2. java.lang 패키지 (0) | 2023.01.30 |