[JAVA] IO 스트림(2)

msung99·2022년 5월 12일
0
post-thumbnail

FileInputStream

  • 텍스트 파일 외에도 그림, 오디오, 비디오 파일등 모든 종류의 파일을 읽을 수 있음

  • InputStream 의 하위 클래스. 바이트 단위로 처리함

  • 객체 생성방법

    • 1) 생성자에 파일의 경로를 직접 적어주기
    • 2) 그 경로를 가지고 있는 파일 객체를 생성자에 전달하기
    • 파일이 존재하지 않으면 예외 발생
public static void main(String[] args) {   // 만일 try-catch 블록 안쓸거면 main 뒤쪽에다 throws Exception 선언
  try{              // "C:/Temp.java" 라는 경로가 없는경우 예외가 발생하고, try-catch 로 이를 처리함
    FileInputStream fis = new FileInputStream("C:/Temp.java "); // 생성자에 파일의 경로를 직접 적어줌
    int data;
    while( (data = fis.read() != -1) {
     System.out.write(data);      // FileInputStream 을 통해 파일로 부터 읽어온 내용을 콘솔창에 써줌(출력)
    }
    fis.close();
   } catch(Exception e){
     e.printStackTrace();  // printStackTrace : 예외처리할때 가장 많이 쓰이는 예외처리 메소드
     System.out.println("error");
   }

FileOutputStream

  • 모든 종류 데이터를 파일로 저장

  • 객체 생성방법

    • 이미 존재하는 파일을 덮어쓰는 것인지 주의할것!
      (같은 이름의 파일이 있다면 덮어씌운다. 즉, 생성자에다 같은 경로를 또 지정해주면 새롭게 덮어씌움 )
  • 형태

    • 첫번쨰 인자 : 파일 경로
    • 두번째 인자 : true 또는 false => true로 지정시, 현재 파일에 기록된 내용 뒤에다 내용을 추가하겠다는 것. 즉, 기존에 만들어진 파일을 삭제하지 않고 뒤에다 내용을 계속 추가
FileOutputstream fis = new FileOutputStream("C:/Temp/data.txt", true);

예제

String originFileName = "C:/Temp/house.jpg"   // 원본파일 경로
String targetFileName = "C:/Temp/house.jpg";  // 복사할 파일 경로

FileInputStream fis = new FileInputStream(originFileName);
FileOutputStream fos = new FileOutputStream(targetFileName);

int readByteNo;
byte[] byte_array = new byte[100];

// 이미지 파일 복사. 이미지 파일은 우리가 봤을때만 그림이지, 컴퓨터가 봤을때는 바이트 덩어리이다.
while( (readByteNo = fis.read(byte_array)) != -1) {
  fos.write(byte_array, 0, readByteNo);
}

fos.flush();
fos.close()
fis.close();

System.out.println("복사가 잘 되었습니다");

FileReader

  • 텍스트 파일로부터 데이터를 읽어들임
  • char 배열 사용

FileWriter

  • 텍스트 파일에 문자 데이터 저장할 때 사용

보조 스트림

  • 다른 스트림과 연결되어 여러가지 편리한 기능을 제공해주는 스트림

  • 기존 스트림에 그대로 사용하되, 기존 스트림 기능 외에도 보조 스트림의 기능까지도 이용할 수 있다.


문자변환 보조 스트림 - InputStreamReader, InputStreamWriter, OutputStreamReader, OutputStreamWriter

InputStreamReader : 바이트 입력 스트림을 문자 입력 스트림으로 변환

  • InputStream으로 읽어온 바이트 단위로 읽어온 후, 문자로 변환해주는 작업을 InputStreamReader 라는 보조스트림이 대신 수행한다.

OutputStreamReader : 바이트 출력 스트림을 문자 출력 스트림으로 변환

  • 같은 맥락으로, 바이트 단위처리 스트림인 OutputStream 을 활용해 문자단위를 파일에 출력해 주고싶을때, 출력해주는 바이트 단위 데이터들을 문자단위로 변환해 주는 작업을 OutputStreamReader 보조스트림이 대신 수행해준다.
  • InputStreamReader : 바이트 단위 처리 스트림인 InputStream 을 직접 내부에서 이용하지만, 바이트 단위로 받아온 것을 문자 단위로 변환

    • 보조 스트림 InputStreamReader 가 그 내부에 InputStream 을 가지고 있다.
  • OutputStreamReader : InputStreamReader 의 반대개념

객체 생성하기
1. 객체 생성시, 생성자 인자값
InputStreamReader 는 객체 생성시에 생성자의 인자로 InputStream 객체를 (또는 InputStream 의 하위클래스 객체 ) 를 받는다.

  • 마찬가지로 OutputStreamReader 는 생성자의 인자로 OutputStream 객체,
    OutputStreamWriter 는 OutputStream 을,
    InputStreamWriter 는 InputStream 을 받는다.

2.형태 : 변환할타입에관한스트림 변수명 = new 보조스트림명(타입을변환해야할객체)
ex1) FileOutputStream fos = new FileOutputStream("C:/Temp/file1.txt");
Writer write1 = new OutputStreamWriter(fos); // file1.txt 파일로 부터 읽어온 바이트 타입 데이터들을 문자 타입으로 변환


ex2) InputStream is = System.in;
Reader read1 = new InputStreamReader(is); // 콘솔에서 읽어온 바이트 데이터들을 문자 타입으로 변환

예제1 - InputStreamReader

InputStream is = System.in;   // 콘솔에서 내용을 읽어옴
Reader reader = new InputStreamReader(is);  // 콘솔에서 읽어온 바이트 단위 내용을 문자 단위로 처리
// InputStreamReader 의 생성자 인자로 System.in 을 넣는다
//  InputStream reader = new InputStreamReader(is);  로 선언해도 상관x => InputStreamReader 자체가 Reader 를 상속받아 만들어진것이기 때문에 업캐스팅이 가능

/*
결론적으로 InputStreamReader 안에 InputStream 가 들어있게 된다.
실제로 입력값과 연결되서 데이터를 가져오는 것은 InputStream 이 하며, 
내 프로그램이 사용하는 것은 InputStream 을 직접 사용하는 것이 아니라,  
InputStreamReader 의 메소드를 사용해서 내부적으로 바이트로 들어오는 데이터들을 문자 단위로 변환할 수 있다.
*/


int readCharNo;
char[] cbuf = new char[100];

while((readCharNo = reader.read(cbuf)) != -1){    // InputStreamReader 을 사용하지 않고 그냥 InputStream 을, 즉 System.in 을 사용하게 되면 바이트 배열로 처리해야함. InputStreamReader 을 사용해서 char 배열로 처리할 수 있다!
  String data = new String(cbuf, 0, readCharNo);
  System.out.println(data);
}

reader.close();

예제2 - OutputStreamWriter

FileOutputStream fos = new FileOutputStream("C:/Temp/file1.txt");
Writer writer = new OutputStreamWriter(fos);

String data = "바이트 출력 스트림을 문자 출력 스트림으로 변환";
writer.write(data);    

// FileOutputStream 은 OutputStream 을 상속받은 애이다. 
// 그런데 FileOutputStream 으로 String 타입(문자 타입)을 직접 받아서 처리할 수 없다. 
// ( OutputStream 를 비롯한 OutputStream 을 상속받은 클래스들은 String 을 타입을 처리할 수 있는 write() 메소드는 없다.)
// 따라서 파일과 직접적으로 연결된 FileOutputStream 으로 String 타입을 처리할떄는
//  OutputStreamWriter 안에다 이 FileOutputStream 을 넣으면 String 타입을 처리할 수 있다!

wrtier.flush();
writer.close();
System.out.println("파일 저장이 끝났습니다.");

BufferedStream

  • 처리속도가 빠른 보조스트림

종류

  • BufferedInputStream, BufferedReader
  • BufferedOutputStream, BufferedWriter
InputStream is = System.in;
Reader reader = new InputStreamReader(is);  // InputStream x타입을 InputStreamReader 에 넣음
// 이러면 InputStream으로 콘솔에서 바이트 단위로 읽어온 데이터를 InputStreamReader 를 통해 문자 단위로 처리가 가능해진다.

BufferedReader br = new BufferedReader(reader);

/*
 => InputStream 을 InputStreamReader 가 감싸고있고,  InputStreamReader 를 BufferedReader 가 감싸고 있는 형태
InputStream 으로 콘솔에서 바이트 단위로 데이터를 읽어오면, InputStreamReader 가
InputStream 을 감싸고 있으므로 문자 단위로 사용할 수 있게되고,
또 BufferedReader가 InputStreamReader 을 감싸고 있으므로 
내부에 가지고 있는 버퍼에 값을 기록하면서 더 효울적이고 빠르게 값을 읽어올 수있게 된다.
*/ 

System.out.println("입력:");
String lineString = br.readLine();  // BufferedReader 에서 지원해주는 메소드 readLine()

System.out.println("출력:" + lineString);

DataInputStream, DataOutputStream

  • 8개의 기본 데이터 타입(int, double, .. 등등) 의 각 바이트 크기에 해당하는 모든 내용이 크기만큼 그대로 기록

    • 바이트 단위로 나눠서 처리하는 것이 아닌, 있는 그대로 처리

프린터 보조 스트림 : PrintStream, PrintWriter

  • PrintStream : OutputStream 상속받음
  • PrintWriter : Writer 상속받음

메소드

  • print()
  • println()

우리가 지금까지 써왔던
System.out.println() 에서 System.out 의 데이터 타입이 PrintStream 타입이다.

그렇기 때문에 PrintStream 의 print() 와 println() 을 사용할 수 있었던 것!

예제

  • FileOutputStream 을 PrintStream 안에 넣어서 PrintStream 객체인 ps 를 만듬.

FileOutputStream 객체 fos 는 print(), println() 과 같은 메소드가 없어서 사용 못했지만, PrintStream 로 객체로 한번 감싸서 사용가능해짐


profile
블로그 이전했습니다 🙂 : https://haon.blog

0개의 댓글