럿고의 개발 노트
[프로그래머스] 자바 중급 > Part5. IO 본문
[프로그래머스] 자바 중급
Part5. IO
1. 자바IO
입출력을 위한 인터페이스와 클래스들임.
크게 byte단위 입출력과 문자 단위 입출력클래스로 나뉨.
- byte단위 입출력클래스는 모두 InputStream, OutputStream이라는 추상클래스를 상속받아 만들어 짐.
- 문자(char)단위 입출력클래스는 모두 Reader와 Writer라는 추상클래스를 상속받아 만들어 짐.
4가지 추상클래스(InputStream, OutputStreamReader, Reader, Writer)를 받아들이는 생성자가 있다면, 다양한 입출력방법을 제공하는 클래스
4가지 클래스를 받아들이는 생성자가 없다면, 어디로부터 입력받을 것인지, 어디에 쓸것인지를 나타내는 클래스
파일로 부터 입력받고 쓰기 위한 클래스
- FileInputStream
- FileOutputStream
- FileReader
- FileWriter
배열로 부터 입력받고 쓰기 위한 클래스
- ByteArrayInputStream
- ByteArrayOutputStream
- CharReader
- CharWriter
위의 8개의 해당 클래스들은 어디로부터, 어디에라는 대상을 지정할 수 있는 IO클래스로 이런 클래스를 장식대상 클래스라고 함.
DateInputStream, DataOutputStream같은 클래스를 보면 다양한 데이터 형을 입출력 함.
PrintWriter는 다양하게 한줄 출력하는 println()메소드를 가지고 있음.
BufferedReader는 한줄 입력받는 readLine()메소드를 가짐.
- 다양한 방식으로 입출력 기능을 제공하며, 이런 클래스를 장식 클래스라고 함.
데코레이터 패턴(Decorator Pattern) : 하나의 클래스를 장식 하는 것처럼 생성자에서 감싸서 새로운 기능을 계속 추가 할 수 있도록 클래스를 만드는 방식
2. Byte 단위 입출력
Byte단위 입출력 클래스 이름이 InputStream, OutputStream으로 끝남.
파일로 부터 읽어오기 위한 객체(FileInputStream)
파일에 쓸수 있게 해주는 객체(FileOutputStream)
read()메소드가 byte를 리턴한다면 끝을 나타내는 값을 표현할 수 없기 때문에 byte가 아닌 int를 리턴함.
음수의 경우 맨 좌측 비트가 1이 되며 읽어들일 것이 있다면 항상 양수를 리턴함.
FileInputStream과 FileOutputStream을 이용하여, 1바이트씩 읽어들여 1바이트씩 저장
read()메소드가 리턴하는 타입은 정수인데, 정수 4바이트 중 마지막 바이트에 읽어들인 1바이트를 저장
read()메소드는 더이상 읽을 것이 없다면 -1을 리턴
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteExam1 {
public static void main(String[] args) {
/* 클래스 이름이 InputStream이나 OutputStream으로 끝남
* 파일로 부터 1byte씩 읽어들여 파일에 1byte씩 저장하는 프로그램 작성
*/
long startTime = System.currentTimeMillis();
FileInputStream fis = null; // 읽기 기능
FileOutputStream fos = null; // 쓰기 기능
try {
fis = new FileInputStream("src/part5/ByteExam1.java");
fos = new FileOutputStream("byte.txt");
int readData = -1; // 읽었을때 값을 담기 위한 변수
// 음수의 경우 맨좌측이 1이 됨
while((readData = fis.read()) != -1) { // 파일이 끝났다면 -1을 반환
fos.write(readData);
}
} catch (Exception e) {
e.printStackTrace();
}finally { // 반드시 인스턴스화가 되면 닫아줘야함!
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("실행시간 : " + (endTime - startTime));
}
}
3. Byte 단위 입출력 심화
- System.currentTimeMillis() : 현재 시간을 롱타입으로 반환
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteExam2 {
public static void main(String[] args) {
// 파일로 부터 512byte씩 읽어들여 파일에 512byte씩 저장하는 프로그램 작성
// ByteExam1보다 많이 읽어들여서 쓰기때문에 속도가 더 빠를것
long startTime = System.currentTimeMillis();
FileInputStream fis = null; // 읽기 기능
FileOutputStream fos = null; // 쓰기 기능
try {
fis = new FileInputStream("src/part5/ByteExam1.java");
fos = new FileOutputStream("byte.txt");
int readCount = -1; // 읽었을때 값을 담기 위한 변수
byte[] buffer = new byte[512];
while ((readCount = fis.read(buffer)) != -1) { // 파일이 끝났다면 -1을 반환
fos.write(buffer, 0, readCount);
}
} catch (Exception e) {
e.printStackTrace();
} finally { // 반드시 인스턴스화가 되면 닫아줘야함!
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("실행시간 : " + (endTime - startTime));
/* 속도차이가 나는 이유
* 1byte씩 읽는 경우 보통 512byte씩 읽어옴 그후 1byte만 쓰고 511byte는 버림
* 그다음 또 512byte를 읽어온 후 1byte만 쓰고 511byte는 버림
* 어차피 OS에서 512byte씩 읽어오기때문에, 파일을 읽어올때 512byte배수로 읽어오는 것이 성능상 좋음
*
*/
}
}
4. 다양한 타입의 출력
try-with-resources 블럭 선언
java io객체는 인스턴스를 만들고, 모두 사용하면 close() 메소드를 호출
close()메소드를 사용자가 호출하지 않더라도, Exception이 발생하지 않았다면 자동으로 close()가 되게 할 수 있는 방법
try( //io객체 선언 ){ //io객체 사용 }catch(Exception ex){ ex.printStackTrace(); }
다양한 타입으로 저장 할 수 있는 DataOutputStream
- writeInt() - 정수값으로 저장
- writeBoolean() - 논리값으로 저장
- writeDouble() - 실수값으로 저장
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class ByteExam3 {
public static void main(String[] args) {
/* IO패키지는 무조건 close를 해줘야함.
* 자동으로 종료시켜주는 방법도 있음
* try-with-resources : 사용한 자원을 자동으로 종료 시켜주는 기능
*/
try(
DataOutputStream out = new DataOutputStream(new FileOutputStream("data.txt"));
){
out.writeInt(100); // 정수값으로 저장
out.writeBoolean(true); // 논리값으로 저장
out.writeDouble(50.5); // 실수값으로 저장
}catch (Exception e) {
e.printStackTrace();
}
}
}
5. 다양한 타입의 입력
- data.dat로부터 값을 읽어들여 화면에 출력하는 클래스
- 다양한 타입의 데이터를 읽어낼 수 있는 DataInputStream
- readInt() - 정수를 읽어들이는 메소드
- readBoolean() - 논리값을 읽어들이는 메소드
- readDouble() - 실수값을 읽어들이는 메소드
- 파일에 저장된 순서대로 읽어 들여야 한다.
import java.io.DataInputStream;
import java.io.FileInputStream;
public class ByteExam4 {
public static void main(String[] args) {
//data.txt를 값을 읽어들여 화면에 출력
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();
}
}
}
6. Char 단위 입출력(Console)
- char단위 입출력 클래스는 클래스 이름이 Reader나 Writer로 끝남.
- char단위 입출력 클래스를 이용해서 키보드로 부터 한줄 입력 받아서 콘솔에 출력
- System.in : 키보드를 의미(InputStream)
- BufferedReader : 한줄씩 입력받기 위한 클래스로 생성자는 InputStream을 입력받는 생성자가 없음.
- System.in은 InputStream 타입이므로 BufferedReader의 생성자에 바로 들어갈 수 없으므로 InputStreamReader 클래스를 이용
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class CharIOExam1 {
public static void main(String[] args) {
/* char 단위 입출력
* Reader나 Writer로 끝나는 메소드들이 Char 단위 입출력
* char단위 입출력 클래스를 이용하여 키보드로 부터 한줄 입력 받아서 콘솔에 출력
* System.in : 키보드를 의미(type : InputStream)
* BufferedReader : 한줄씩 입력 받기 위한 클래스
* InputStreamReader : 리더를 상속받아, System.in을 Reader형태로 변환
* 데코레이터 패턴(Decorator Pattern) : 객체에 추가적인 기능을 동적으로 첨가하는 방식
* 서브클래스를 만드는 것을 통해 기능을 유연하게 확장할 수 있는 방법 제공
*/
String line = null;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
line = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(line);
}
}
7. Char 단위 입출력(File)
- 파일에서 읽기 위해 FileReader 클래스 이용
- 한 줄 읽어 들이기 위해 BufferedReader 클래스 이용
- readLine() 메소드가 한줄씩 읽게 해주며, 더 이상 읽어 들일 내용이 없을때는 null을 리턴
- 파일에 쓰게하기 위해서 FileWriter 클래스 이용
- 편리하게 출력하기 위해서 PrintWriter 클래스 이용
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class CharIOExam2 {
public static void main(String[] args) {
/* 파일로부터 한줄씩 입력받아서 파일에 출력
* FileReader : 파일에서 읽기 위해
* BufferedReader : 한 줄 읽어 들이기 위해
* FileWriter : 파일에 쓰기 위해
*/
BufferedReader br = null;
PrintWriter pw = null;
try {
br = new BufferedReader(new FileReader("src/part5/CharIOExam2.java"));
pw = new PrintWriter(new FileWriter("test.txt"));
String line = null;
while((line = br.readLine()) != null) { // 파일이 끝나면 null을 입력
pw.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
br.close();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
출처
'Java Note > [프로그래머스] 자바 중급(동영상 강의)' 카테고리의 다른 글
[프로그래머스] 자바 중급 > Part6. 어노테이션 (0) | 2020.02.04 |
---|---|
[프로그래머스] 자바 중급 > Part4. 날짜와 시간 (0) | 2020.02.04 |
[프로그래머스] 자바 중급 > Part3. java.util 패키지 (0) | 2020.01.31 |
[프로그래머스] 자바 중급 > Part2. java.lang 패키지 (0) | 2020.01.31 |
[프로그래머스] 자바 중급 > Part1. Object 클래스 (0) | 2019.12.06 |