독학/자바

[혼공학습단 10기] 자바 week6

최연재 2023. 8. 15. 14:48

미션

기본미션 : 입출력 스트림 요약 정리하여 포스팅하기

아래 글을 확인해주세요!

 

선택미션 : p. 632 문제 2번 풀고, 풀이 과정 설명하기

답 코드 : 

FileReader fr = new FileReader(filePath);
BufferedReader br = new BufferedReader(fr);
		
int rowNum = 1;
while (true) {
    String data = br.readLine();
    if (data == null) break;
    System.out.println(rowNum++ + ": " + data);
}
br.close();

 

설명 : 

1~2번 줄을 통해 문자 기반 입력 스트림을 얻고, BufferedReader 보조스트림에 연결합니다. rowNum 변수는 라인 번호를 표시하는 용도로 사용합니다. 반복문 내에서는 먼저 라인 단위로 문자열을 읽고 해당 문자열을 data에 대입합니다. data == null이라면 파일의 끝에 도달했다는 것이므로 반복문에서 탈출합니다. 파일의 끝에 도달하지 않았다면 라인 번호를 포함해서 내용을 출력합니다. (rowNum은 후위) 반복문이 끝나고 입력 스트림을 닫습니다. 

 

(교재에 수록된 정답 코드와는 살짝 다릅니다. 교재 정답 코드의 경우 반복문 파트가 더욱 간결합니다.)


여기부터 입출력 스트림 요약 정리(기본미션)입니다!

Chapter 14 입출력 스트림

1. 입출력 스트림

📌 입출력 스트림의 종류

- 바이트 기반 스트림 : 바이너리 데이터를 입출력 시 사용

  • 바이트 기반 입출력 스트림의 최상위 클래스 : InputSteam, OutputStream

- 문자 기반 스트림 : 문자 데이터 입출력 시 사용

  • 문자 기반 입출력 스트림의 최상위 클래스 : Reader, Writer

 

 

📌 바이트 출력 스트림 : OutputStream

- 바이트 기반 출력 스트림의 최상위 클래스로 추상 클래스, 모든 바이트 기반 출력 스트림 클래스는 OutputStream 클래스를 상속받아 만들어짐.

- OutputStream 클래스의 주요 메소드

① write(int b) 메소드

  • 리턴 타입 : void
  • 매개변수로 주어지는 int에서 끝 1바이트만 출력스트림으로 보냄.

② write(byte[] b) 메소드

  • 리턴 타입 : void
  • 매개값으로 주어진 배열의 모든 바이트를 출력스트림으로 보냄.

③ write(byte[] b, int off, int len) 메소드

  • 리턴 타입 : void
  • b[off]부터 len개의 바이트를 출력스트림으로 보냄.

④ flush() 메소드

  • 리턴 타입 : void
  • 출력 버퍼에 잔류하는 모든 바이트 출력

⑤ close() 메소드

  • 리턴 타입 : void
  • 출력 스트림을 닫음.

 

 

📌 바이트 입력 스트림 : InputStream

- 바이트 기반 입력 스트림의 최상위 클래스로 추상 클래스, 모든 바이트 기반 입력 스트림 클래스는 InputStream 클래스를 상속받아 만들어짐.

- InputStream 클래스의 주요 메소드

① read() 메소드

  • 리턴 타입 : int
  • 입력 스트림으로부터 1바이트를 읽고 int 타입으로 리턴
  • 리턴된 4바이트 중에서 끝 1바이트에만 데이터가 들어 있음.
  • 더 이상 입력 스트림으로부터 바이트를 읽을 수 없다면 -1을 리턴함.

② read(byte[] b)

  • 리턴 타입 : int
  • 입력 스트림으로부터 매개값으로 주어진 배열의 길이만큼 바이틀르 읽고 해당 배열을 저장함.
  • 읽은 바이트 수를 리턴함.
  • 더 이상 입력 스트림으로부터 바이트를 읽을 수 없다면 -1을 리턴함.

③ read(byte[] b, int off, int len)

  • 리턴 타입 : int
  • 입력 스트림으로부터 len개의 바이트만큼 읽고, 매개값으로 주어진 바이트 배열 b[off]부터 len개까지 저장
  • 읽은 바이트 수인 len개를 리턴함.
  • off가 0이고, len을 배열의 길이로 준다면  read(byte[] b)와 동일함.
  • 더 이상 입력 스트림으로부터 바이트를 읽을 수 없다면 -1을 리턴함.

④ close() 메소드

  • 리턴 타입 : void
  • 입력 스트림을 닫음.

 

 

📌 문자 출력 스트림 : Writer

- 문자 기반 출력 스트림의 최상위 클래스로 추상 클래스, 모든 문자 기반 출력 스트림 클래스는 Writer 클래스를 상속받아 만들어짐.

- Writer 클래스의 주요 메소드

① write(int c) 메소드

  • 리턴 타입 : void
  • 매개 변수로 주어지는 int에서 끝 2바이트(1개의 문자)만 출력 스트림으로 보냄.

② write(char[] cbuf) 메소드

  • 리턴 타입 : void
  • 매개값으로 주어진 배열의 모든 문자를 출력 스트림으로 보냄

③ write(char[] cbuf, int off, int len) 메소드

  • 리턴 타입 : void
  • cbuf[off]부터 len개의 문자를 출력 스트림으로 보냄

④ write(String str) 메소드 

  • 리턴 타입 : void
  • 문자열 전체를 출력 스트림으로 보냄

⑤ write(String str, int off, int len) 메소드

  • 리턴 타입 : void
  • 주어진 문자열 off 순번부터 len개까지의 문자를 출력 스트림으로보냄.

⑥ flush() 메소드

  • 리턴 타입 : void
  • 버퍼에 잔류하는 모든 문자 출력

⑦ close() 메소드

  • 리턴 타입 : void
  • 출력 스트림을 닫음

 

 

📌 문자 입력 스트림 : Reader

- 문자 기반 입력 스트림의 최상위 클래스로 추상 클래스, 모든 문자 기반 입력 스트림은 Reader 클래스를 상속받아 만들어짐.

- Reader 클래스의 주요 메소드

① read() 메소드

  • 리턴 타입 : int
  • 입력 스트림으로부터 1개의 문자(2바이트)를 읽고 int 타입으로 리턴
  • 리턴된 4바이트 중 끝 2바이트에 문자 데이터가 들어있음. 
  • 더 이상 입력 스트림으로부터 문자를 읽을 수 없다면 read() 메소드는 -1을 리턴

② read(char[] cbuf) 메소드

  • 리턴 타입 : int
  • 입력 스트림으로부터 매개값으로 주어진 문자 배열의 길이만큼 문자를 읽고 배열에 저장
  • 읽은 문자 수를 리턴, 문자를 더 이상 읽을 수 없다면- 1을 리턴
  • 많은 양의 문자를 읽을 때는 read() 메소드 대신 read(char[] cbuf) 메소드를 사용하는 것이 좋음( ∵ 읽는 횟수 : read(char[] cbuf) < read())

③ read(char[] cbuf, int off, int len) 메소드

  • 리턴 타입 : int
  • 입력 스트림으로부터 len개의 문자만큼 읽고 매개값으로 주어진 문자 배열에서 cbuf[off]부터 len개까지 저장
  • 읽은 문자 수인 len을 리턴, 문자를 더 이상 읽을 수 없다면- 1을 리턴
  • off가 0이고, len이 배열 길이라면 read(char[] cbuf)와 동일

④ close() 메소드

  • 리턴 타입 : void
  • 입력 스트림을 닫음.

 

 

2. 보조 스트림

📍 보조 스트림 : 다른 스트림과 연결되어 여러가지 편리한 기능을 제공해주는 스트림(자체적인 입출력 불가)

📌 보조스트림 연결하기

- 보조 스트림 생성

보조스트림 변수 = new 보조스트림(연결스트림);
  • 보조스트림의 생성자 매개값은 또 다른 보조스트림이 될 수 있음.
  • ex
InputStream is = System.in;
InputStreamReader reader = new InputStreamReader(is);
BufferedReader br = new BufferedReader(reader);

 

 

📌 문자 변환 보조 스트림

- 소스 스트림이 바이트 기반 스트림이고 입출력 데이터가 문자라면 Reader, Writer로 변환해서 사용할 수 있음.( ∵ 문자 입출력은 Reader, Writer가 더 편리함.)

- OutputStreamWriter : 바이트 기반 출력 스트림에 연결되어 문자 출력 스트림인 Writer로 변환하는 보조 스트림

Writer writer = new OutputStreamWriter(바이트 기반 출력 스트림);

- InputStreamWriter : 바이트 기반 입력 스트림에 연결되어 문자 입력 스트림인 Reader로 변환하는 보조 스트림

Reader reader = new InputStreamReader(바이트 기반 입력 스트림);

 

 

📌 성능 향상 보조 스트림

- 프로그램의 성능은 입출력이 가장 늦은 장치를 따라가므로 아래와 같은 방법을 사용해 실행 성능을 향상시킬 수 있음.

- 프로그램이 입출력 소스와 직접 작업하지 않고, 중간에 메모리 버퍼와 작업하기 -> 버퍼가 가득 차면 데이터를 한 번에 하드디스크로 보냄.

- 메모리 버퍼를 추가로 제공하는 보조 스트림

① BufferedOutputStream

  • 바이트 기반 출력 스트림에 연결되어 버퍼를 제공하는 보조 스트림
  • 프로그램에서 전송한 데이터를 내부 버퍼에 두다가 버퍼가 가득 차면 모든 데이터를 한 번에 보냄
  • 메모리 버퍼로 데이터를 고속전송하므로 출력 성능 향상 효과가 있음
BufferedOutputStream bos = new BufferedOutputStream(바이트 기반 출력 스트림);

② BufferedInputStream

  • 바이트 기반 입력 스트림에 연결되어 버퍼를 제공하는 보조 스트림
  • 입력 소스로부터 자신의 내부 버퍼 크기만큼 데이터를 미리 읽고 버퍼에 저장함.
  • 프로그램은 외부의 입력 소스로부터 직접 읽는 대신 버퍼로부터 읽음으로써 읽기 성능이 향상됨.
BufferedInputStream bis = new BufferedInputStream(바이트 기반 입력 스트림);

③ BufferedWriter

  • 문자 기반 출력 스트림에 연결되어 버퍼를 제공하는 보조 스트림
  • 프로그램에서 전송한 데이터를 내부 버퍼에 두다가 버퍼가 가득 차면 모든 데이터를 한 번에 보냄
  • 메모리 버퍼로 데이터를 고속전송하므로 출력 성능 향상 효과가 있음
BufferedWriter bw = new BufferedWriter(문자 기반 출력 스트림);

④ BufferedReader

  • 문자 기반 입력 스트림에 연결되어 버퍼를 제공하는 보조 스트림
  • 입력 소스로부터 자신의 내부 버퍼 크기만큼 데이터를 미리 읽고 버퍼에 저장함.
  • 프로그램은 외부의 입력 소스로부터 직접 읽는 대신 버퍼로부터 읽음으로써 읽기 성능이 향상됨.
BufferedReader br = new BufferedReader(문자 기반 입력 스트림);
  • BufferedReader는 라인 단위로 문자열을 읽는 readLine() 메소드를 제공함. (\r, \n 이전의 모든 문자열을 읽고 리턴)

 

 

📌 기본 타입 입출력 보조 스트림

- DataInputStream, DataOutputStream 보조 스트림을 연결하면 기본 타입인 boolean, char, short, int, long, float, double을 입출력할 수 있음.

- 생성

DataInputStream dis = new DataInputStream(바이트 기반 입력 스트림);
DataOutputStream dos = new DataOutputStream(바이트 기반 출력 스트림);

- 메소드

  • boolean : readBoolean(), writeBoolean(boolean v)
  • byte : readByte(), writeByte(int v)
  • char : readChar(), writeChar(int v)
  • double : readDouble(), writeDouble(double v)
  • float : readFloat(), writeFloat(float v)
  • int : readInt(), wrirteInt(int v)
  • long : readLong(), writeLong(long v)
  • short : readShort(), writeShort(int v)
  • String : readUTF(), writeUTF(String str)

- 데이터 타입의 크기가 모두 다르므로 DataOutputStream으로 출력한 데이터를 다시 DataInputStream으로 읽을 때는 출력한 순서와 동일한 순서로 읽어야 함.

 

 

📌 프린터 보조 스트림

- 프린터와 유사하게 출력하는 print(), println() 메소드를 가지고 있는 보조 스트림

PrintStream ps = new PrintStream(바이트 기반 출력 스트림);
PrintWriter pw = new PrintWriter(문자 기반 출력 스트림);

 

 

📌 객체 입출력 보조 스트림

- ObjectOutputStream과 ObjectInputStream 보조 스트림을 연결하면 메모리에 생성된 객체를 파일 또는 네트워크로 출력할 수 있음.

ObjectInputStream ois = new ObjectInputStream(바이트 기반 입력 스트림);
ObjcetOutputStream oos = new ObjectOutputStream(바이트 기반 출력 스트림);

- ObjectOutputStream

  • 객체를 직렬화 : 객체를 바이트 배열로 만듦
oos.writeObject(객체);

- ObjectInputStream

  • 객체를 역직렬화 : 바이트 배열을 객체로 복원.
객체 타입 변수 = (객체 타입) ois.readObject();

- 자바는 모든 객체를 직렬화하지 않음. 

  • java.io.Serializable 인터페이스를 구현한 객체만 직렬화함.
  • Serializable 인터페이스는 메소드 선언이 없는 인터페이스
  • 객체를 파일로 전송하거나, 네트워크로 전송할 목적이라면 클래스 선언 시 implements Serializable을 추가해야 함.

 

 

3. 입출력 관련 API

📍콘솔

  • 시스템을 사용하기 위해 키보드로 입력을 받고 모니터로 출력하는 소프트웨어
  • 유닉스, 리눅스 운영체제는 터미널, 윈도우 운영체제에서는 명령 프롬프트에 해당.

📌System.in 필드

- 자바는 콘솔로부터 데이터를 입력받을 때 System.in을 사용함.

InputStream is = System.in;

- 키보드로부터 입력된 키 확인 : read() 메소드 사용

- 엔터키가 입력된후 라인 단위로 전체 문자열을 읽는 방법

Reader reader = new InputStreamReader(is);
BufferedReader rs = new BufferedReader(reader);

String lineStr = br.readLine();

 

 

📌 System.out 필드

- 자바는 콘솔에 데이터를 출력할 때 System.out을 사용함.

- System.out은 PrintStream 타입의 필드이기 때문에 print(), println(), printf()와 같은 메소드를 이용해서 모니터로 출력 가능

 

 

📌 Scanner 클래스

- 입출력 스트림, 보조 스트림이 아님.

- 문자 파일이나 바이트 기반 입력 스트림에서 라인 단위 문자열을 쉽게 읽도록 하기 위해 java.util 패키지에서 제공하는 클래스

Scanner scanner = new Scanner(System.in);
String inputData = scanner.nextline();

 

 

 

📌 File 클래스

- java.io 패키지에서제공하는 클래스로, 파일 및 폴더 정보를 제공함.

- File 클래스로부터 File 객체를 생성하려면 문자열 경로를 제공해야 함.

- 해당 경로에 실제로 파일이나 폴더가 있는지 확인하기 : exists() 메소드 호출

File file = new File("C:/Temp/file.txt")
boolean isExist = file.exists();

- exists() 메소드의 리턴값이 false일 때 파일, 폴더 생성하기

  • createNewFile() :  새로운 파일 생성, 리턴 타입 boolean
  • mkdir() : 새로운 폴더 생성, 리턴 타입 boolean
  • mkdirs() : 경로상에 없는 모든 폴더 생성, 리턴 타입 boolean

- exists() 메소드의 리턴값이 true일 때 사용할 수 있는 메소드

  • delete() : 파일 또는 폴더 삭제, 리턴 타입 boolean
  • canExecute() : 실행 가능한 파일인지 여부 확인, 리턴 타입 boolean
  • canRead() : 읽을 수 있는지 파일인지 여부 확인, 리턴 타입 boolean
  • canWrite() : 수정 및 저장할 수 있는지 파일 여부 확인, 리턴 타입 boolean
  • getName() : 파일의 이름 리턴, 리턴 타입 String
  • getParent() : 부모 폴더 리턴, 리턴 타입 String
  • getParentFile() : 부모 폴더를 File 객체로 생성 후 리턴, 리턴 타입 String
  • getPath() : 전체 경로 리턴, 리턴 타입 String
  • isDirectory() : 폴더인지 여부 확인, 리턴 타입 boolean
  • isFile() : 파일인지 여부 확인, 리턴 타입 boolean
  • isHidden : 숨김 파일인지 여부 확인, 리턴 타입 boolean
  • lastModified() : 마지막 수정 날짜 및 시간 리턴, 리턴 타입 long
  • length() : 파일의 크기 리턴, 리턴 타입 long
  • list() : 폴더에 포함된 파일 및 서브 폴더목록 전부를 String 배열로 리턴, 리턴 타입 String[]
  • list(FilenameFilter filter) : 폴더에 포함된 파일 및 서브 폴더 목록 중에 FilenameFilter에 맞는 것만 String 베열로 리턴, 리턴 타입 String[]
  • listFiles() : 폴더에 포함된 파일 및 서브 폴더 목록 전부를 Files 배열로 리턴, 리턴 타입 File[]
  • listFiles(FilenameFilter filter) : 폴더에 포함된 파일 및 서브 폴더 목록 중에 FilenameFilter에 맞는 것만 File 배열로 리턴, 리턴 타입 File[]

- 파일 또는 폴더의 정보를 얻기 위해 File 객체를 단독으로 사용할 수 있지만 파일 입출력 스트림(FileInputStream, FileOutputStream, FileReader, FileWriter) 객체를 생성할 때 경로 정보를 제공할 목적으로도 사용 가능.


이렇게 6주 동안의 혼공학습단 활동이 끝났습니다! 자바 1회독을 방학 동안 했으니 2학기에 전공 수업으로 다시 자바를 복습하면서 공부할 생각입니다. 

 

혼공학습단을 하면서 다른 분들이 공부하신 걸 보고 같이 힘낼 수 있어서 좋았습니다. 이번 겨울에 혼공학습단을 하게 된다면 컴구+운체를 하지 않을까 싶습니다. 다들 수고 많으셨습니다🥰