자바의 입출력을 위한 스트림
: 자바는 다양한 입출력 장치에 독립적으로 일관성 있는 입출력을 입출력 스트림을 통해 제공한다.
자바 I/O란 데이터를 읽고 쓰는 작업을 말한다.
입출력 스트림 구분
대상 기준 | 입력 스트림 / 출력 스트림 |
자료의 종류 | 바이트 스트림 / 문자 스트림 |
기능 | 기반 스트림 / 보조 스트림 |
입력 스트림과 출력 스트림
입력 스트림 : 대상으로부터 자료를 읽어들이는 스트림
출력 스트림 : 대상으로 자료를 출력하는 스트림

스트림의 종류
종류 | 예시 |
입력 스트림 | FileInputStream, FileReader, BufferedInputStream, BufferedReader 등 |
출력 스트림 | FileOutputStream, FileWriter, BufferedOutputStream, BufferedWriter 등 |
바이트 단위 스트림과 문자 단위 스트림
바이트 단위 스트림 : 동영상, 음악 파일, 실행 파일 등의 자료를 읽고 쓸 때 사용
문자 단위 스트림 : 바이트 단위로 자료를 처리하면 문자는 깨짐, 인코딩에 맞게 2바이트 이상으로 처리하도록 구현된 스트림
종류 | 예시 |
바이트 스트림 | FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream 등 |
문자 스트림 | FileReader, FileWriter, BufferedReader, BufferedWriter 등 |
기반 스트림과 보조 스트림
기반 스트림 : 대상에 직접 자료를 읽고 쓰는 기능의 스트림
보조 스트림 : 직접 읽고 쓰는 기능은 없이 성능 향상이나 추가적인 기능을 더해주는 스트림
- FileInputStream 예제
input.txt에 asdf라고 적혀있다는 전제 하에 결과 화면은 다음과 같이 나타난다.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 | package ch02; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class FileInputStreamTest2 { // main 함수 public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream("input.txt"); int data; // 마지막에 읽을 값이 없다면 -1을 반환 System.out.println(">>> 기사 시작 <<<"); while ((data = fis.read()) != -1) { System.out.print((char) data); } System.out.println("\n>>> 기사 종료 <<<"); } catch (FileNotFoundException e) { System.out.println("파일을 찾을 수 없어요."); } catch (IOException e) { System.out.println("입력 스트림 동작시 오류 발생했어요."); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } // end of main } // end of class 결과 화면 >>> 기사 시작 <<< asdf >>> 기사 종료 <<< | cs |
→ FileInputStream은 바이트 입력 스트림이다.
→ while문에서 i = fis.read() 의 뜻은 FileInputStream을 읽어온 값을 i에 저장한다는 뜻이고,
!= -1은 그 값의 마지막에 읽을 값이 없다면 -1을 반환하기 때문에 -1이 아닐 때까지 값을 입력하도록 한 방식이다.
→ 값을 읽어올 때 (char)로 형 변환을 해서 읽어와야 한다.
→ 선언부에서 null을 저장하고 초기화 해주는 이유는 선언과 동시에 초기화를 하면 finally문에서 fis.close();가 되지 않기 때문이다.
아 너무 어려운데 ?
- FileInputStream 예제
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 31 32 33 34 35 36 37 38 39 40 | package ch03; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStream2 { // main 함수 public static void main(String[] args) { FileOutputStream fos = null; try { byte[] bs = new byte[26]; byte myData = 65; fos = new FileOutputStream("output2.txt"); // 파일에다가 A - Z 까지 알파벳을 출력하고 싶다면 코드 작성 방법은 ? // 반복 횟수 - for for (int data = 0; data < bs.length; data++) { fos.write(myData); myData++; // 65 - A, 66 - B } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } // end of main } // end of class <결과 화면> ABCDEFGHIJKLMNOPQRSTUVWXYZ | cs |
→ FileOutputStream은 바이트 기반 출력으로 파일을 생성해주는 스트림이다.
→ 파일에 A - Z 까지 알파벳으로 출력하기 위해 배열을 알파벳 갯수만큼 26개 저장한다.
→ 바이트 기반 출력 스트림이므로 유니코드 65가 'A'이므로 myData에 65를 저장하고 for문을 이용하여 output2.txt 파일에 출력하였다.
- FileReader 예제
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 31 32 33 | package ch04; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; //FileInputStream, FileOutputStream --> 바이트 기반 // FileReader, FileWriter --> 문자열 기반 public class FileReaderTest1 { // main 함수 public static void main(String[] args) { // 문자 단위로 읽어들이는 스트림 FileReader fr = null; try { fr = new FileReader("output2.txt"); int data; while ((data = fr.read()) != -1) { System.out.print((char) data); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // end of main } // end of class | cs |
→ FileReader는 문자열 기반으로 파일을 읽어오는 스트림이다.
→ InputStream은 한글이 깨지지만, FileReader는 한글이 깨지지 않고 파일을 읽어 올 수 있다.
→ while문에서 data = fr.read() 의 뜻은 FileReader를 읽어온 값을 i를 저장하고,
!= -1은 그 값의 마지막에 읽을 값이 없다면 -1을 반환하기 때문에 -1이 아닐 때까지 값을 읽어오도록 하는 방식이다.
FileReader로 파일 읽어와서 FileWriter로 파일 생성하기
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package ch04; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class MyArticle { public static void main(String[] args) { // 입력 대상 : article1.txt // 출력 대상 : today_article.txt FileReader fr = null; FileWriter fw = null; try { fr = new FileReader("article1.txt"); fw = new FileWriter("today_article.txt"); int data; fw.write("MCN 뉴스\n"); while ((data = fr.read()) != -1) { fw.write(data); } fw.write("\n작성자 : 홍길동"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fr.close(); fw.close(); } catch (IOException e) { e.printStackTrace(); } } } // end of main } | cs |
→ FileReader로 article1.txt의 파일을 읽어와서 FileWriter의 today_article.txt에 출력하는 예제이다.
→ FileWriter로 반복문을 이용하여 FileReader파일을 읽어온 후 fw.write(data)를 해주어 today_article.txt 파일에 출력하였다.
보조 스트림(BufferedInputStream, BufferedOutputStream)을 활용하여 성능 높이기
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | package ch05; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class MainTest3 { // main 함수 public static void main(String[] args) { long milliSecond = 0; // 1 FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("chapter02.zip"); fos = new FileOutputStream("chpater02copy.zip"); // 보조 스트림 활용하기 ! (성능 향상을 위해서) BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos); int i; milliSecond = System.currentTimeMillis(); while ((i = bis.read()) != -1) { bos.write(i); } milliSecond = System.currentTimeMillis() - milliSecond; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("파일 복사 시 소요시간 : " + milliSecond); } // end of main } // end of class | cs |
→ 파일을 읽고 쓸 때 기반 스트림을 바로 쓰는 것보다 보조 스트림을 사용하면 성능이 더 향상된다.
→ 보조 스트림을 생성하고 생성자 안에 매개변수로 기반 스트림의 변수명을 넣어주면 된다.
DataOutputStream, DataInputStream을 이용하여 데이터 생성하고 읽어오기
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | package ch06; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class MainTest1 { // main 함수 public static void main(String[] args) { FileOutputStream fos = null; try { fos = new FileOutputStream("data.txt"); // 보조 기반 스트림 활용 DataOutputStream dos = new DataOutputStream(fos); // dos.write(100); dos.writeChar('A'); dos.writeInt(10); dos.writeFloat(3.14F); dos.writeUTF("TEST UTF8"); dos.flush(); // 잊지마 ! } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } FileInputStream fis = null; try { fis = new FileInputStream("data.txt"); // 보조 스트림 + data DataInputStream dis = new DataInputStream(fis); char a = dis.readChar(); System.out.println(a); System.out.println(dis.readInt()); System.out.println(dis.readFloat()); System.out.println(dis.readUTF()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // end of main } // end of class <결과 화면> A 10 3.14 TEST UTF8 | cs |
→ DataInputStream은 InputStream을 생성자의 매개변수로 받아 DataInputStream을 생성하고, DataOutputStream은 OuputStream을 생성자의 매개변수로 받아 DataOutputStream을 생성한다.
→ 자료형별 메서드를 가져서 read자료형(), write자료형()을 사용하여 입력하거나 출력할 수 있다.
→ flush()란 출력 버퍼를 비울 때 사용하는데 꼭 사용해주어야 한다.
'프로그래밍 > Java' 카테고리의 다른 글
Java_람다식(Lambda Expression) (1) | 2023.03.22 |
---|---|
Java_소켓(Socket) 통신 (0) | 2023.03.04 |
Java_컬렉션 프레임워크 (0) | 2023.02.21 |
Java_Thread (0) | 2023.02.17 |
Java_Swing 키보드 방향키로 이미지를 창 안에서만 움직이게 하기 (0) | 2023.02.16 |