ch14. 입출력 스트림

728x90

ch14. 입출력 스트림

14-1. 입출력 스트림 (기본 스트림)

[입출력 스트림의 종류]

: java.io 패키지는 多 종류의 스트림 제공

  • 바이트’ 기반 스트림

: 바이너리 데이터 입출력 스트림

출력 최상위 클래스 : OutputStream

입력 최상위 클래스 : InputStream

  • 문자’ 기반 스트림

: 문자 데이터 입출력 스트림

출력 최상위 클래스 : Writer

입력 최상위 클래스 : Reader

📗[바이트 ‘출력’ 스트림] : OutputStream

: 바이트 기반 출력 스트림의 최상위 클래스, 추상 클래스
: OutputStream 클래스 -> 모든 바이트 기반 출력 스트림의 기본 메소드들 정의

write(int b) 메소드 : 한 번에 1byte씩만 보냄

: 매개변수 int(4byte)의 끝 1byte씩만 출력 스트림으로 보냄

write( 배열 ) 메소드 : 한 번에 배열 전체 바이트 모두 보냄

: 한 번에 매개값 배열 속 모든 바이트를 출력 스트림으로 보냄

witre(배열, int off, int len) 메소드 : 한 번에 배열 일부 바이트 지정해서 보냄

: 한 번에 매개값 배열 속 off 시작 위치부터 len개 만큼의 바이트를 출력 스트림으로 보냄

📗[바이트 ‘입력’ 스트림] : InputStream

: 바이트 기반 입력 스트림의 최상위 클래스, 추상 클래스
: InputStream 클래스에는 바이트 기반 입력 스트림의 기본 메소드들 정의

read() 메소드 : 한 번에 1byte씩 읽고 int(4byte)타입으로 리턴

: 입력 스트림으로부터 1byte씩 읽고,4byte를 리턴하는데, 리턴된 4byte 의 끝 1바이트에만 데이터가 들어있

read( 배열 ) 메소드 : 한 번에 매개값 길이만큼 읽음

: 입력 스트림으로부터 한 번에 매개값 배열 길이만큼 읽어서 해당 배열에 저장 후, 읽은 바이트 수 리턴

: 실제 읽은 바이트 수 < 배열 길이 : 실제 읽은 바이트 수 리턴

: 한 번에 많은 양 바이트 읽을 때 효율적 O

예) 100바이트 읽을 때 -> read() : 1바이트씩 100번 반복 읽음

→ read( byte ) : 한 번 읽을 때 배열 길이만큼 읽기 때문에 읽는 횟수 적음

read( 배열, int off, int len) 메소드 :한 번에 len만큼 읽고 배열 off 위치부터 차례로 저장
: 입력 스트림으로부터 한 번에 len개 바이트 읽고 해당 배열 off부터 len개 바이트 저장시킨 후 읽은 바이트 수 리턴

 **( 차이점 )**
  • 한 번에 읽어들이는 바이트 수 len 매개값으로 조절 O
  • 배열 저장 시작 인덱스 위치 off 매개값으로 지정 O

📗[문자 ‘출력’ 스트림] : Writer

: 문자 기반 출력 스트림의 최상위 클래스, 추상 클래스
: Writer 클래스는 모든 문자 기반 출력 스트림 기본 메소드들 정의

write( int ) 메소드 : 한 번에 한 문자(2byte)씩 보냄

: 매개변수 int(4byte)에서 끝의 2byte 씩 (1개 문자만) 출력 스트림으로 보냄

write( 배열 ) 메소드 : 한 번에 배열 전체 문자 모두 보냄

: 매개값 char[] 배열 속 모든 문자를 출력 스트림으로 보냄

write( 배열, int off, int len) 메소드 : 한 번에 배열 일부 문자 지정해서 보냄

: 매개값 char[] 배열 속 off위치부터 len개 문자만큼 출력 스트림으로 보냄

write( String str ) 메소드 : 문자열 전체를 출력 스트림으로 보냄

write ( String str, int off, int len) 메소드 : 주어진 문자열 일부 지정해서 보냄

📗[문자 ‘입력’ 스트림] : Reader

: 문자 기반 입력 스트림의 최상위 클래스, 추상 클래스
: Reader 클래스는 문자 기반 입력 스트림 기본 메소드들 정의해둠

read() 메소드 : 한 번에 1개 문자씩 (2byte) 읽음

: 입력 스트림으로부터 1개 문자(2byte)씩 읽고 int(4byte)타입 리턴
: 리턴된 4byte 중 끝 2byte에만 문자 데이터 O
: 리턴된 int값 -> char타입 강제 타입 변환시키면 실제로 읽은 문자 얻을 수 있다.

read( 배열 ) 메소드 : 한 번에 매개값 배열 길이만큼 문자 읽음

: 입력 스트림으로부터 매개값 배열 길이만큼 문자 읽고 해당 배열에 저장 후 , 읽은 문자 수 리턴

: 한 번에 많은 양 문자 읽을 때 효율적 O

예) 100문자 읽을 때 -> read() : 1문자씩 100번 반복 읽음
-> read( byte ) : 한 번 읽을 때 배열 길이만큼 읽기 때문에 읽는 횟수 적음

read ( 배열 , int off, int len) 메소드 : 한 번에 len개 문자만큼 읽음

: 입력 스트림으로부터 len개 문자 만큼 읽어서 매개값 배열 off위치부터 len개 문자 저장 후, 읽은 문자 수 리턴

( 차이점 )

  • 한 번에 읽어들이는 문자 수 len 매개값으로 조절 O
  • 배열 저장 시작 인덱스 위치 off 매개값으로 지정 O

14-2. 보조 스트림

[보조 스트림]

: 다른 스트림에 연결되어 추가 기능 제공하는 보조적 스트림
: 보조 스트림은 자체적으로 입출력 수행 불가능하기 때문에, 반드시 연결되어 사용 O
: 문자 변환/입출력 성능 향상/기본타입 입출력/프린트 출력 보조/객체 입출력 등의 기능O
: 보통, 기본 입출력 스트림 <-> 프로그램 사이에 존재하면서 중간 역할하는 보조 스트림

[보조 스트림 연결하기]

: 보조 스트림 객체 생성과 동시에 연결
: 생성자 매개값에 자신이 연결될 스트림 대입시켜 연결함

  • 기본 입출력 스트림과 연결 O
    : 보조 스트림의 생성자 매개값에 기본 입출력 스트림 연결
  • 보조 스트림끼리 연속 연결 O
    : 보조 스트림의 생성자 매개값에 또 다른 보조 스트림이 올 수 O
    : 즉, 보조 스트림에 다시 보조 스트림 연결 사용도 가능 O

📗[’문자 변환’ 보조 스트림]

: 기본 입출력 스트림은 ‘바이트 기반’ 스트림인데/ 프로그램 입출력 데이터는 ‘문자’인 경우,
그 중간을 매개하며 연결될 보조 스트림이 바이트 기반 스트림 -> 문자 기반 스트림 변환 역할

✅OutputStreamWriter

: 바이트 기반 출력 스트림에 연결되어 문자 출력 스트림 Writer로 변환시키는 ‘보조 스트림’

Writer writer = new OutputStreamWriter(연결);
        //보조 스트림 생성 직후 바로 문자 기반 스트림 타입 변수에 대입시킴

✅InputStreamReader

: 바이트 기반 입력 스트림에 연결되어 문자 입력 스트림 Reader로 변환시키는 ‘보조 스트림’

Reader reader = new InputStreamReader(연결);
        //보조 스트림 생성 직후 바로 문자 기반 스트림 타입 변수에 대입시킴

📗[’성능 향상’ 보조 스트림] : 버퍼 보조 스트림

: 추가로 메모리 버퍼 제공하여 프로그램 실행 성능 향상시키는 보조 스트림

: 프로그램 실행 성능은 입출력이 가장 늦는 ‘하드 디스크’ 입출력 처리 속도를 따른다.
: 프로그램이 직접 하드디스크까지 가지 X, 버퍼 보조 스트림 사용하여 실행 성능 향상 O

  • 바이트 기반 버퍼 스트림 : BufferedInputStream, BufferedOutputStream
  • 문자 기반 버퍼 스트림 : BufferedReader, BufferedWriter

[출력 버퍼 보조 스트림]

✅BufferedOutputStream

: 바이트 기반 출력 스트림에 연결되어 버퍼 제공하는 보조 스트림

BufferedOutputStream a = new BufferedOutputStream(연결 스트림);

BufferedWriter

: 문자 기반 출력 스트림에 연결되어 버퍼 제공하는 보조 스트림

BufferedWriter a = new BufferedWriter(연결 스트림);

[기능] : 프로그램에서 전송한 데이터 -> 내부 버퍼에 쌓음 -> 꽉차면 모든 데이터 한꺼번에 보냄

[프로그램 성능 향상] : 굳이 하드디스크까지 갈 필요 X
: 메모리 버퍼로 데이터 고속 전송 가능해져서 출력 성능 향상

[입력 버퍼 보조 스트림]

✅BufferedInputStream

: 바이트 기반 입력 스트림에 연결되어 추가 버퍼 제공하는 보조 스트림

BufferedInputStream a = new BufferedInputStream(연결);

BufferedReader

: 문자 기반 입력 스트림에 연결되어 추가 버퍼 제공하는 보조 스트림

BufferedReader a = new BufferedReader(연결);

[기능]: 입력 스트림으로부터 자기 내부 버퍼만큼 데이터 미리 읽어 버퍼에 저장해둠

[프로그램 성능 향상]: 프로그램은 메모리 버퍼로부터 데이터 고속 읽기 가능해져서 읽기 성능 향상

[기본 타입 입출력 보조 스트림] : (바이트 기반)

: 프로그램 입출력 데이터가 ‘기본타입’인 경우 보조 스트림 이용 O
: 기본적으로 바이트 타입 입출력 스트림과 연결되어 사용됨 O

DataInputStream

DataInputStream a = new DataInputStream(연결);

DataOutputStream

DataOutputStream a = new DataOutputStream(연결);

: 기본 타입 입출력을 위해 기본타입의 데이터 타입별로 입출력 메소드 제공

예) 입력 메소드 : readBoolean(), readByte(), readInt(), readLong(), readFloat() ...
예) 출력 메소드 : writeBoolean(), writeByte(), writeInt(), writeUTF() ...

(주의) : 기본 타입들 간에도 데이터 타입 크기 모두 다르므로

DataOutputStream으로 출력한 데이터를 ‘다시’ DataInputStream으로 읽어올 때는 출력 순서와 동일한 순서로 읽어와야 한다.

[프린터 보조 스트림] : Only 출력 보조

: PrintStream(바이트 기반 출력 보조) / PrintWriter(문자 기반 출력 보조)

print(), println() 메소드를 제공

→ [System.out] 은 PrintStream타입이기 때문에 print(), println() 사용 O

✅PrintStream

PrintStream p = new PrintStream(연결);

✅PrintWriter

PrintWriter a = new PrintWriter(연결);

: 데이터 출력을 위해 출력할 데이터 타입 별로 메소드 재정의해서 제공함

print() 메소드 : \n 없이 데이터를 출력, 개행 X
println() 메소드 : 출력할 데이터 끝에 \n 추가, 개행 O 줄바꿈 O

➕’라인 단위’로 문자열 읽어오기

→ BufferedReader 스트림이 제공 메소드 : readLine()

: ‘라인 단위’로 문자열 읽고 리턴
: /r, /n 직전의 모든 문자열 읽고 리턴
: 더 읽을 라인 X -> null 리턴

→ 라인 단위로 문자열 얻고 싶을 때, BufferedReader 보조 스트림 생성 후, readLine() 반복 호출하다가 null 반환하면 블록 탈출시키면 됨

➕라인 단위’로 문자열 출력하기

→Print 보조 스트림이 제공 메소드 : println()

: ‘라인 단위’로 문자열 출력
: 문자열 끝에 \n 개행 문자 포함 출력

| println() 메소드로 출력한 내용은 readLine() 메소드로 읽을 때 매우 편리하다
println() 메소드는 출력 시 개행 문자 포함시켜 출력하고
readLine() 메소드는 개행 문자 직전까지를 읽어서 반환하기 때문이다. |
| --- |

[객체 입출력 보조 스트림] : (바이트 기반)

: ObjectOutputStream , ObjectInputStream 보조 스트림을 연결하면
메모리에 생성된 객체를 (파일 or 네트워크에) 입출력 할 수 있다.
: 프로그램 <-> 바이트 기반 입출력 스트림 사이에서 객체를 입출력 시키기 위해 중간역할함

✅ObjectOutputStream

: 객체를 직렬화하는 역할 (객체 -> 바이트)

ObjectOutputStream a = new ObjectOutputStream(연결);

: 이 보조 스트림이 제공하는 writeObject(객체) 메소드 매개값 객체 직렬화해서 출력 스트림으로 보냄

✅ObjectInputStream

: 객체로 역직렬화하는 역할 (바이트 -> 객체 복원)

ObjectInputStream a = new ObjectInputStream(연결);

: 이 보조 스트림이 제공하는 readObject() 메소드

입력 스트림에서 읽은 바이트를 역직렬화해서 객체로 다시 복원 후 리턴

(주의) 기본적으로 리턴 객체 타입이 Object 타입이므로 마지막에 원래 타입으로 강제 변환 필요

객체타입 변수 = (강제타입) a.readObject();
  • 자바는 모든 객체를 직렬화 X
  • 자바는 Serializable 인터페이스 구현한 객체만 직렬화 O
  • 파일 저장 목적 or 네트워크로 전송 목적인 ‘객체’ = 직렬화(바이트로 변환 필요)
  • 용도에 따라 직렬화가 필요한 객체 사용할 경우, 개발자는 해당 클래스 선언 시 implement Serializable 추가하여 선언

Serializable 인터페이스 : 메소드 선언 없는 인터페이스

List 컬렉션의 구현 클래스 ArrayList : Serializable 인터페이스 구현한 클래스

따라서 ArrayList에 저장되는 객체 역시 직렬화 통해 파일 저장 가능 O

(단, ArrayList에 저장되는 객체 역시 Serializable을 구현한 객체여야 한다. )

14-3. 입출력 관련 API

  • 콘솔로부터 데이터 입력받을 때 System.in을 사용
  • 콘솔에 데이터 출력할 때 System.out을 사용
  • 콘솔에 에러 출력할 때 System.err을 사용

📗[System.in 필드]

-자바는 콘솔에서 키보드의 데이터 입력받을 수 있도록 System클래스의 in 정적 필드 제공함
[System.in]은 InputStream 타입의 필드. InputStream 변수로 참조 가능

: 참조 상태에서는 InputStream의 read() 메소드로 입력된 데이터를 1byte씩만 읽을 수 있고, 리턴된 값에는 해당 키코드 값(int) 저장되어 있다.

✅[System.in] 이용하여 읽되 ‘라인 단위’로 통문자열 읽고 싶은 경우

System.in필드 이용 → 라인 단위로 읽기 위해서는 여러 가지 보조 스트림 연결 작업이 추가적으로 필요

InputStream is = System.in; 
① Reader reader = new InputStreamReader(is); 
② BufferedReader br = new BufferedReader(reader);

String lineStr = br.readLine();

📗[System.out 필드]

:자바는 콘솔에서 모니터로 데이터 출력할 수 있도록 System클래스의 out 정적 필드 제공

[System.out] 은 PrintStream 타입의 필드

→ PrintStream이 제공하는 print(). println(), printf() 메소드 이용

📗[Scanner 클래스]

  • [java.util 패키지에서 제공]하는 클래스
  • ‘라인 단위’ 문자열 쉽게 읽기 위해 생김
  • Scanner는 따로 보조 스트림 추가할 번거로움X
  • 자체적으로 nextLine() 메소드 제공

: (\n) 직전까지 입력된 ‘라인 단위’ 문자열 읽어서 반환

[기본 구조]

import java.util *;
 Scanner scanner = new Scanner(System.in);
 String a = scanner.nextLine();

📗[File 클래스]

  • [java.io 패키지]에서 제공하는 File 클래스
  • ( 파일 or 폴더 )와 관련된 정보 제공해주는 역할 多
  • File 클래스로부터 File 객체 생성 시, 생성자 매개값에 (객채 생성할 위치) 문자열 경로 대입
File file = new File(“C:/Temp/file.txt”);’

→ File 객체 생성했다고 바로 파일.폴더 생성 X
→ File 객체 생성 후 해당 경로에 실제로 파일. 폴더 없는 상태여도 따로 예외 발생 X

➕<해당 경로에 실제로 파일.폴더 존재 여부 확인>

: File 객체 생성 -> exists() 메소드 호출

▪️exists() 메소드 리턴값 : true 또는 false 일 때

→ 아래 메소드로[ ‘파일 or 폴더’ 생성 O ]

createNewFile() : 새로운 파일 생성

mkdir() : 새로운 폴더 생성

mkdirs() : (경로상에 없는) 모든 폴더를 생성

▪️exists() 메소드 리턴값 : true 일 때

→ 아래 메소드로 [ ‘파일 or 폴더’ 정보 획득 O ]

delete() : 파일 or 폴더 삭제

canExecute() : 실행 가능 파일 여부 확인

canRead() : 읽기 가능 파일 여부 확인

canWrite() : 쓰기 가능 파일 여부 확인

getName() : 파일 이름 리턴

getParent() : 부모폴더 리턴

getParentFile() : 부모폴더를 File 객체로 생성후 -> 리턴

getPath() : 전체 경로 리턴

isDirectory() : 폴더인지 확인

isFile() : 파일인지 확인

isHidden() : 숨김 파일 여부 확인

lastModified() : 마지막 수정 날짜,시간 리턴

length() : 파일 크기 리턴

list() 폴더에 포함된 하위 폴더 목록 전부 → String 배열로 리턴

list(filter) : 폴더에 포함된 하위 폴더 목록

FilenameFilter에 맞는 것만 -> String 배열로 리턴

listFiles() : 폴더에 포함된 하위 폴더 목록 전부 -> File 배열로 리턴

listFiles(filter):폴더에 포함된 하위 폴더 목록

FilenameFilter에 맞는 것만 -> File 배열로 리턴

🟨[File 객체 이용]

① 파일 또는 폴더의 정보 얻기 위해 사용
② 파일 입출력 스트림 객체 생성 시 → 스트림 생성자 (’매개값’ )에

🔸1)문자열 경로 대입

FileInputStream a = new FileInputStream(“C:/Temp/image.gif”);

🔸2)File 객체 그대로 대입

  File file = new File(“C:/Temp/image.gif”);   
    FileInputStream a = new FileInputStream(file);

728x90

'Java > [문법]_Java(자바)' 카테고리의 다른 글

동빈나_ 정리  (0) 2021.08.30
ch13. 컬렉션 프레임워크  (0) 2021.08.23
ch12. 스레드  (0) 2021.08.23
11-1. java.lang 패키지  (0) 2021.08.11
ch10. 예외 처리  (0) 2021.08.05