일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- TypeScript
- angular
- es6
- Props
- literal
- 10px
- npm
- TS
- font-size
- 타입스크립트
- ES5
- 서버리스 #
- 문서번호
- 으
- 데이터베이스 #try #이중
- 0.25px border
- &연산
- ZOOM
- jwt
- 당근마켓
- 0.75px border
- 0.5px border
- Websocket
- 전역변수
- entity
- github
- 클론코딩
- Strict
- 컴포넌튼
- 1px border
- Today
- Total
복잡한뇌구조마냥
[JAVA] 자바 IO ( Byte 단위, 다양한 타입, Char 단위 입출력) 본문
자바 IO (Input + Output)
- 프로그램 상에서 들어오는 데이터를 Input 데이터
- 프로그램 상에서 나가는 데이터를 Output 데이터
- byte 단위 입출력 클래스는 모두 InputStream과 OutputStream이라는 추상클래스를 상속받아 만들어짐.
- 문자(char) 단위 입출력 클래스는 모두 Reader와 Writer라는 추상클래스를 상속받아 만들어짐
- 4가지 추상클래스를 받아들이는 생성자가 있다면, 다양한 입출력방법을 제공하는 클래스임.
- 4가지 클래스를 받아들이는 생성자가 없다면, ①어디로부터 입력받을 것인지, ②어디에 쓸것인지를 나타내는 클래스
- 파일로부터 입력받고 쓰기 위한 클래스 : FileInputStream, FileOutputStream, FileReader, FileWriter
- 배열로부터 입력받고 쓰기 위한 클래스 : ByteArrayInputStream, ByteArrayOutputStream, CharReader, CharWriter
- 해당 클래스들은 어디로부터, 어디에 라는 대상을 지정할 수 있는 IO 클래스
- 장식대상 클래스
- DataInputStream, DataOutputStream 같은 클래스를 보면 다양한 데이터 형을 입력받고 출력함.
- PrintWriter는 다양한 한줄 출력하는 println() 메소드를 가지고 있음
- BufferedReader는 한줄 입력받는 readLine()메소드를 가짐
- 다양한 방식으로 입력하고, 출력하는 기능을 제공
- 장식하는 클래스
Byte 단위 입출력
- Byte 단위 입출력 클래스는 클래스의 이름이 InputStream이나 OutputStream으로 끝남.
- 파일로 부터 1byte씩 읽어들여 파일에 1byte씩 저장하는 프로그램 작성
- 파일로 부터 읽어오기 위한 객체 - FileInputStream
- 파일에 쓸 수 있게 해주는 객체 - FileOutputStream
- read() 메소드
- byte를 리턴한다면 끝에 나타내는 값을 표현할 수 없기 때문에, byte가 아닌 int를 return함
- 음수의 경우 맨 좌측 비트가 1이 됨.
- 읽어들일 것이 있다면 항상 양수를 return 함
- FileInputStream과 FileOutputStream을 이용하여 1바이트씩 읽고 1바이트씩 쓰기
- read() 메소드가 return 하는 타입은 정수, 정수 4바이트중 마지막 바이트에 읽어들인 1바이트를 저장.
- read() 메소드는 더이상 읽어들일 것이 없을 때, -1을 return 함
// src/javaIO/exam/ByteExam1.java
package javaIO.exam;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class ByteExam1 {
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 (Exception e) {
e.printStackTrace();
} try{
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
- 현재 파일을 읽어들여서 특정 파일에 값을 복사하는 코드
- ByteExam1.java파일을 실행했더니 byte.txt 파일에 ByteExam1.java파일의 내용과 동일한 내용을 복사함.
- FileInputStream과 FileOutputStream은 Exception을 통해서 예외처리가 필요함
- 사용이 끝나면 close() 메소드를 통해서 끝내줘야함. close 메소드도 Exception 처리 필요.
byte 배열을 이용한 입출력
// src/javaIO/exam/ByteExam2.java
package javaIO.exam;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class ByteExam2 {
public static void main(String[] args) {
long start = 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 (Exception e) {
e.printStackTrace();
} try{
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
- 파일로부터 512 byte씩 읽어서 buffer 라는 배열에 저장하는 방식을 이용해서 512 byte씩 입출력
- int를 이용해서 1byte씩 읽는 것과 속도차이가 많이나는 것을 확인할 수 있음. ( Exam1에서는 38, Exam2에서는 3)
512바이트씩 읽는 방법이 빠른 이유
- OS에서 파일을 읽을 때, 512 byte씩 읽어오도록 되어 있음.
- 1byte씩 읽는 방식은 512 byte를 읽어와서 1byte를 제외한 나머지 511byte를 버림 (비효율적)
- 따라서 512의 배수로 배열을 잡아주는 것이 파일을 읽고 쓰기에 성능상 유리함.
다양한 타입의 입출력
try-with-resources
- 사용한 자원을 자동으로 종료시켜주는 기능
- java io객체는 인스턴스를 만들고, 모두 사용하면 close()메소드를 호출해야함
- 사용자가 호출하지 않더라도, Exception이 발생하지 않았다면 자동으로 close()가 되는 방법임.
try(
// io객체 선언
){
// io객체 사용
}catch(Exception ex){
// 예외처리
}
다양한 타입의 입출력
출력
package javaIO.exam;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class ByteExam3 {
public static void main(String[] args) {
try(
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
) {
dos.writeInt(100);
dos.writeBoolean(true);
dos.writeDouble(50.5);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- DataOutputStream을 이용해서 다양한 타입을 저장
- writeInt() - 정수값 저장
- wirteBoolean() - boolean 값 저장
- wirteDouble() - double 값 저장
- 데이터 값이 저장된 것이기 때문에 숫자 나 문자로 표시된것이 아님.
- 4 byte (int) + 1 byte (boolean) + 8 byte (double) = 13 byte
입력
- DataInputStream을 이용해서 다양한 타입을 저장
- readInt() - 정수값 불러오기
- readBoolean() - boolean 값 불러오기
- readDouble() - double 값 불러오기
package javaIO.exam;
import java.io.DataInputStream;
import java.io.FileInputStream;
public class ByteExam4 {
public static void main(String[] args) {
try(
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
) {
int i = dis.readInt();
boolean b = dis.readBoolean();
double d = dis.readDouble();
System.out.println(i);
System.out.println(b);
System.out.println(d);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 만들어진 파일을 읽어서 다양한 타입의 값을 사용할 수 있음.
- 파일에 저장된 순서대로 읽어야함.
- int, boolean, double 순서대로 저장했기 때문에 읽을 때도 동일한 순서로 읽어야함.
Char 단위 입출력
- Char 단위 입출력 클래스는 클래스 이름이 Reader나 writer로 끝남
Console
- char 단위 입출력 클래스를 이용해서 키보드로부터 한줄 입력을 받아서 콘솔에 출력
- System.in - 키보드를 의미 ( InputStream )
- BufferedReader - 한줄씩 입력 받기 위한 클래스
- BufferedReader 클래스의 생성자는 InputStream을 입력받는 생성자가 없음
- System.in은 InputStream 타입이므로 BufferedReader의 생성자에 바로 들어갈 수 없으므로 InputStreamReader 클래스를 이용
package javaIO.exam;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class CharIOExam1 {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String line = br.readLine();
System.out.println(line);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 한줄 입력받아서 line이라는 변수에 넣고 console 로 출력하는 방식
- System.in 을 생성자에 사용할 때 쓴 방식은 데코레이터 패턴이라고 볼 수 있음.
- 데코레이터 패턴을 이용해서 키보드 입력이 아닌 파일 입력도 가능함.
- readLine 문법을 할 때, try-catch 구문 사용 필요.
* 데코레이터 패턴 (Decorator Pattern)
- 객체에 추가적인 요건(기능)을 동적으로 첨가하는 방식
- 서브클래스를 만드는 것을 통하여 기능을 유연하게 확장할 수 있는 방법 제공
File
- 파일에서 한 줄씩 입력 받아서 파일에 출력
- 파일에서 읽기 위해서 FileReader 클래스 이용
- 한 줄 읽어들이기 위해서 BufferedReader 클래스 이용
- BuffedReader 클래스가 가지고 있는 readLine() 메소드가 한줄씩 읽게 해줌.
- readLine() 메소드는 읽어낼 때 더 이상 읽어들일 내용이 없으면 null을 return함
- 파일에 쓰게하기 위해서 FileWriter 클래스 이용
- 편리하게 출력하기 위해서 PrintWriter 클래스 이용
- 출력할 때 많이 사용하는 System.out도 PrintWriter 객체임
package javaIO.exam;
import java.io.*;
public class CharIOExam2 {
public static void main(String[] args) {
BufferedReader br = null;
PrintWriter pw = null;
try{
br = new BufferedReader(new FileReader("src/javaIO/exam/CharIOExam2.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 (Exception e) {
e.printStackTrace();
}
}
}
}
- close() 메소드를 이용해서 항상 종료시켜줘야함.
- test.txt파일에 내용이 복사된 것을 확인 할 수 있음.
'BE > JAVA' 카테고리의 다른 글
[JAVA] 쓰레드 ( Thread ) (2) | 2025.06.18 |
---|---|
[JAVA] 어노테이션 (Annotation) (1) | 2025.06.17 |
[JAVA] 날짜와 시간 ( Date, Calendar, java.time ) (2) | 2025.06.14 |
[JAVA] 컬렉션 프레임워크 ( 자료구조, Set, List, Map ) (1) | 2025.06.10 |
[JAVA] java.lang + 오토박싱 (1) | 2025.06.09 |