[정리] IO(입출력)

2022. 8. 17. 09:53·🚀 from error to study/Java

IO(Input & Output: 입출력)

 

항상 기준은 프로그램임!

외부 매체는 파일, 모니터, 스피커 등이 있으나 일단 제일 간단하게 실습은 "파일"로 진행

 

(기준)

프로그램  ===>  파일

프로그램  <=== 파일

 

데이터가 움직이기 위해서는 통로가 필요한데 이 통로를 "스트림"이라고 함

 

<스트림의 특징>

- 단방향(입력, 출력 스트림이 따로 존재해야 함)

- 선입선출(먼저 전달한 값이 먼저 나오는 Queue 구조를 가지고 있음)

-이러한 특징 때문에 시간 지연(delay)가 발생할 수 있음

 

<스트림의 구분>

- 통로의 사이즈

바이트스트림: 한 번에 1byte짜리만 이동할 수 있는 좁은 통로 => 입력(XXXInputStream) / 출력(XXXOutputStream) 

문자스트림: 한 번에 2byte짜리가 이동할 수 있는 넓은 통로 => 입력(XXXReader) / 출력(XXXWriter)

 

- 외부 매체와의 직접적인 연결 여부

기반스트림: 외부 매체와 직접적으로 연결되는 통로 

보조스트림: 기반스트림만으로 부족한 성능을 향상시켜 주는 용도의 스트림(보조스트림은 기반스트림 없이는 쓸 수 없음)

 

<기반 스트림을 활용하기 위한 순서 (파일 출력편)>

- 하기 예시는 바이트스트림이며, 문자 스트림 사용 시 FileOutputStream메소드 대신 FileWriter 메소드를 사용하면 됨

 

0. 변수 선언 및 null값 초기화(지역 변수 이슈 때문에 연결 끊을 때 변수명 가져다 쓰려면 선언 위치를 try 밖으로 빼야 함)

 

FileOutputStream fout = null;

 

try {

 

1. FileOutputStream 객체 생성 ( == 연결 통로 만들기)

 

fout = new FileOutputStream("a_byte.txt");

 

- 존재하지 않는 파일명을 적을 시 파일 생성 후 통로 만들어짐

- 존재하는 파일명을 적을 시 바로 통로 만들어짐

 

2. 연결 통로로 데이터를 출력: write() 메소드 사용

 

fout.write(97);

fout.write('b');

 

} catch (FileNotFoundException e) {

} catch (IOException e) {

e.printStackTrace();

 

3. 스트림을 다 이용했으면 자원 반납 (== 연결 끊기, finally 구문 이용)

 

} finally { 

 

try {

fout.close();

} catch (IOException e) {

e.printStackTrace();

}

}

 

<기반 스트림을 활용하기 위한 순서 (파일 입력편)>

- 하기 예시는 바이트스트림이며, 문자 스트림 사용 시 FileInputStream메소드 대신 FileReader 메소드를 사용하면 됨

 

0. 변수 선언 및 null값 초기화(지역 변수 이슈 때문에 연결 끊을 때 변수명 가져다 쓰려면 선언 위치를 try 밖으로 빼야 함)

 

FileInputStream fin = null;

 

try {

 

1. FileInputStream 객체 생성 ( == 연결 통로 만들기)

 

fin = new FileInputStream("a_byte.txt");

 

- 존재하지 않는 파일명을 적을 시 오류 남!!

- 반드시 존재하는 파일명을 적어야 함

 

2. 읽어들이기 (== 입력받기: read() 메소드)

System.out.println(fin.read());

- 를 사용해도 무방하긴 하나 반복문 활용하는 게  더 좋음

 

반복문 활용법 (1) 무한반복

while (true) {

 

int value = fin.read();

if(value == -1) {

break;

}

System.out.println(value);

}

 

반복문 활용법 (2) 조건식 내부에 변수 대입 구문 활용 -- 권장되는 방법

int value = 0;

 

while((value = fin.read()) != -1) {

System.out.println(value);

}

 

} catch (FileNotFoundException e) {

} catch (IOException e) {

e.printStackTrace();

 

3. 스트림을 다 이용했으면 자원 반납 (== 연결 끊기, finally 구문 이용)

} finally { 

 

try {

fout.close();

} catch (IOException e) {

e.printStackTrace();

}

}

 

=> 단! 기반 스트림 사용 시 단어 하나하나를 통로를 통해 옮기기 때문에 데이터가 많아질 경우 시간 지연이 더 커짐

=> 이럴 때 통로 중간에 버퍼를 만들어서 하나하나 옮겨진 단어들을 모두 모아놨다가 한 번에 출력하는 게 더 이득!

=> 기반 스트림의 출력 속도 향상됨!

==> 이렇게 기반 스트림의 성능 향상을 해 주는 게 보조 스트림이며 위 설명은 그중 하나인 버퍼드!

 

보조스트림

: 기반 스트림의 부족한 기능들을 확장시킬 수 있는 스트림

=> 입력용 기반 스트림에는 입력용 보조 스트림을 써야 하고

      출력용 기반 스트림에는 출력용 보조 스트림을 써야 함

=> 속도 성능 향상 목적의 보조 스트림: BufferedXXX

 

1. 기반 스트림 생성

기반스트림클래스명 기반스트림객체명 = new 기반스트림클래스명(파일명);

 

2. 기반스트림객체를 매개변수 삼아서 보조스트림객체를 생성

보조스트림클래스명 보조스트림객체명 = new 보조스트림클래스명(기반스트림객체);

 

<보조 스트림을 활용하기 위한 순서 (파일 출력편)>

 

0. 스트림 변수 선언 및 초기화를 코드 한줄로 줄여서 표현

BufferedWriter bw = null;

 

try {

 

1. 기반스트림 객체 생성(메인 연결 통로 만들기)

2. 보조스트림 객체 생성(매개변수로 기반스트림객체를 제시)

=> 1, 2단계 한 번에 표현 가능

bw = new BufferedWriter(new FileWriter((c_buffer.txt"));

 

3. 출력

bw.write("안녕하세요.");

 

} catch (IOExeption e) {

e.printStackTrace();

} finally {

 

4. 자원 반납(반드시) => finally 블록 안에 작성

try {

bw.close();

} catch (IOException e) {

e.printStackTracer();

}

}

 

<보조 스트림을 활용하기 위한 순서 (파일 입력편)>

0. 스트림 변수 선언 및 null 값으로 초기화

BufferedReader br = null;

 

1. 객체 생성 == 통로를 만들겠음

br = new BufferedReader(new FileReader("c_buffer.txt"));

 

2. 입력: BufferedReader 클래스에서 제공하는 메소드로 읽어들이겠다

(System.out.println(br.readLine()); // 줄 단위로 출력해도 무방하나 편의를 위해 반복문 활용)

 

String value = null; // ""로 초기화해도 무방함

while ((value = br.readLine()) != null) {

System.out.println(value);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch(IOException e){

e.printStackTrace();

} finally {

 

3. 연결 통로를 끊겠다 == 자원 반납(반드시) => finally 블럭에 작성

try {

br.close();

} catch (IOException e) {

e.printStackTrace();

}

 

==> 코드 줄이는 법

<try ~ with ~ resource 구문>

=> try(여기) 스트림 객체 생성 구문을 작성하면 생성 후 try 블럭 내용이 실행된 후 알아서 자원 반납됨

 

try() {

     예외가발생할법한구문;

} catch(예외클래스명 e) {

     해당예외발생시실행할구문;

}

 

try(BufferedReader br = new BufferedReader(new FileReader("c_buffer.txt"))){

// 반복문 활용
String value = null;
while((value = br.readLine()) != null) {
System.out.println(value);
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

 

<보조 스트림을 활용하기 위한 순서 (객체 출력편)>

객체 생성

Phone ph = new Phone("아이폰", 1300000);

 

0. 스트림 변수 선언 및 null로 초기화

ObjectOutputStream oos = null;

 

1. 스트림 객체 생성(== 연결 통로를 만들겠다)

try {

oos = new ObjectOutputStream(new FileOutputStream("Phone.txt"));

 

2. 출력: ObjectOutputStream 객체에서 사용하는 writeObject() 메소드 사용

oos.writeObject(ph);

 

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

} finally {

 

3. 자원 반납

try {

oos.close();

} catch (IOException e) {

e.printStackTracer();

}

 

// 직렬화 선언을 하지 않으면 객체를 파일로 내보낼 때 NotSerializableException이 발생
// => 1byte짜리 좁은 통로로 큰 객체가 지나갈 수 없기 때문에 가로로 배열해 주는 과정: 직렬화
public class Phone implements Serializable { // 직렬화 선언

 

<보조 스트림을 활용하기 위한 순서 (객체 입력편)>

try ~ with ~ recource 구문 버전

 

try ( ObjectInputStream ois = new ObjectInputStream(new FileInputStream("phone.txt"))) {

 

     Phone ph = (Phone)osi.readObject();

     System.out.println(ph);

 

} catch (FileNotFoundException e) {

     e.printStackTrace();

} catch (IOException e) {

     e.printStackTrace();

} catch (ClassNotFoundException e) {

     e.printStackTrace();

}

 

<보조 스트림을 활용하기 위한 순서 (객체 배열 출력편)>

try ~ with ~ recource 구문 버전

테스트용 객체 배열

Phone[] arr = new Phone[3]; // [0] [1] [2]

테스트용 데이터 담기

arr[0] = new Phone("아이폰", 1300000);
arr[1] = new Phone("갤럭시", 1500000);
arr[2] = new Phone("플립폰", 2000000);

try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("phones.txt"))){

반복문 이용해서 내보내기


for(int i =0; i < arr.length; i++) {
oos.writeObject(arr[i]);
System.out.println(arr[i]);
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

 

<보조 스트림을 활용하기 위한 순서 (객체 배열 입력편)>

try ~ with ~ recource 구문 버전

 

EOFExeption(End of file): 파일 내용이 끝났음에도 자꾸 출력하고자 할 때 발생하는 오류

=> IOException의 자식임

 

Phone[] ph = new Phone[3];

try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("phones.txt"))) {

// EOFException이 발생할 때까지만 반복을 돌리기
// 예측 불가능한 오류이기 때문에 정확한 조건을 세울 수 없음

while (true) { // 그래서 일단은 무한 반복
System.out.println(ois.readObject());
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (EOFException e) { // while문 무한반복 하다가 언젠가 EOFException이 발생하는 순간 이쪽으로 들어옴
System.out.println("파일을 다 읽었습니다.");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} 

// catch문은 한 구문이 출력된 후 try ~ catch문을 빠져나오기 때문에 후에는 프로그램 종료가 출력됨
System.out.println("프로그램 종료");

저작자표시 (새창열림)
'🚀 from error to study/Java' 카테고리의 다른 글
  • [정리] 네트워크(Network)
  • [문법] 향상된 for문
  • [정리] API, 예외 처리(Exception)
  • [정리] 상속과 다형성, 오버라이딩, 추상클래스, 인터페이스
천재강쥐
천재강쥐
  • 천재강쥐
    디버거도 버거다
    천재강쥐
  • 전체
    오늘
    어제
    • Category (467)
      • 진짜 너무 궁금한데 이걸 나만 몰라...? (0)
      • 💾 Portfolio (2)
      • 🐤 CodingTest (28)
        • Java (20)
        • ᕕ(ꐦ°᷄д°᷅)ᕗ❌ (5)
      • 🚀 from error to study (142)
        • AI (1)
        • Cloud (2)
        • DB (12)
        • Front-End (16)
        • Github (14)
        • Java (39)
        • Mac (7)
        • Normal (29)
        • Server (22)
      • 📘 certificate (44)
        • 📘 리눅스마스터1급 (1)
        • 📘⭕️ 정보처리기사 (40)
        • 📘⭕️ SQLD (3)
      • 📗 self-study (234)
        • 📗 inflearn (35)
        • 📗 생활코딩 (8)
        • 📗 KH정보교육원 당산지원 (190)
      • 🎨 Scoop the others (0)
        • 📖 Peeking into other people.. (0)
        • 🇫🇷 (0)
        • 📘⭕️ 한국사능력검정시험 심화 (11)
        • 오블완 (4)
  • 인기 글

  • hELLO· Designed By정상우.v4.10.1
천재강쥐
[정리] IO(입출력)
상단으로

티스토리툴바