인생을 코딩하다.

[Java] 바이트 단위 입출력 스트림 본문

Java

[Java] 바이트 단위 입출력 스트림

Hyung1 2020. 11. 23. 17:57
728x90
반응형

바이트 단위 스트림

InputStream : 바이트 단위 입력 스트림 최상위 클래스

OutPutStream : 바이트 단위 출력 스트림 최상위 클래스

 

추상 메서드를 포함한 추상 클래스로 하위 클래스가 구현하여 사용 

 

주요 하위 클래스

스트림 클래스(입력) 설명
FileInputStream 파일에서 바이트 단위로 자료를 읽는다.
ByteArrayInputStream Byte 배열 메모리에서 바이트 단위로 자료를 읽는다.
FilterInputStream 기반 스트림에서 자료를 읽을 때 추가 기능을 제공하는 보조 스트림의 상위 클래스.

 

스트림 클래스(출력) 설명
FileOutputStream 바이트 단위로 파일에 자료를 쓴다.
ByteArrayOutputStream Byte 배열에 바이트 단위로 자료를 쓴다.
FilterOutputStream 기반 스트림에서 자료를 쓸 때 추가 기능을 제공하는 보조 스트림의 상위 클래스.

FileInputStream과 FileOutputStream 사용하기

- 파일에 한 바이트씩 자료를 읽고 쓰는데 사용 (한 바이트이기 때문에 문자는 못 읽는다. 한글같이 멀티바이트인 경우는  FileReader, FileWriter를 쓰면 된다.)

- 입력 스트림은 파일이 없는 경우에 예외 발생 (입력 스트림은 읽을 파일이 지정되있는데 없다면, FileNotFoundException이 뜬다.)

- 출력 스트림은 파일이 없는 경우 파일 생성하여 출력 (없으면 생성을 해준다.)

 

FileInputStream 예제 1

package java8.stream.inputstream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;


public class FileInputTest1 {
    public static void main(String[] args) {
        FileInputStream fis = null;

        try {
            fis = new FileInputStream("input.txt");
            int i;

//            // 한 바이트씩 3번 읽어보자.
//            i = fis.read();
//            System.out.print((char) i);
//            // read()에 빨간줄로 에러가 뜰때 try~catch로 또 감싸주어도 되지만, 아래에 FileNotFoundException이 있기 때문에
//            // 그냥 IOException로 바꿔주면 된다. FileNotFoundException은 IOException에 속하기 때문
//            i = fis.read();
//            System.out.print((char) i);
//            i = fis.read();
//            System.out.print((char) i);

            // 끝까지 읽어보자자, 파일에 끝에 도달하면 -1이 반한됨, -1이 아닐때까지 계속
            while ((i = fis.read()) != -1) {
                System.out.print((char) i);
            }

        } catch (IOException e) {
            e.printStackTrace(); // 어디에서 에러가 발생하였는지 추적할 수 있게
        } finally {
            try {
                fis.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("end");
    }
}

input.txt

abcabcabcabcㅁㄴㅇㅁㄴㅇend 
// 한 바이트만 읽기 때문에 멀티바이트인 한글은 깨진다

Try-With-resources를 이용하여 처리했을때 (JDK 7이상에서 가능)

public class FileInputTest1 {
    public static void main(String[] args) {
    
       try (FileInputStream fis = new FileInputStream("input.txt")) {
            int i;
            while ((i = fis.read()) != -1) {
                System.out.println((char) i);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("end");
    }
 }

결과 값은 똑같다.

 

예제 2

package java8.stream.inputstream;

import java.io.FileInputStream;
import java.io.IOException;

public class FileInputTest2 {
    public static void main(String[] args) {

        try(FileInputStream fis = new FileInputStream("input2.txt")) {
            int i;
            byte[] bs = new byte[10];
            while ((i = fis.read(bs)) != -1) {
                for(byte b : bs) {
                    System.out.print((char)b);
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
jeonghyungilonetwothree
// input2.txt
// 결과 
jeonghyung
ilonetwoth
reenetwoth

jeonghyung
ilonetwoth
ree

여기까지 읽었는데 그 뒤  netwoth는 byte[] bs = new byte[10];(Buffer)에 남은 Garbage다. (JAVA - GC에 관한 글 참고)

오버라이드가 안되었기 때문에 그 뒤에 남은 것이 들어온다.

 

이런 경우에는 읽은 갯수만큼 알아야한다. 통채로 출력하면 Garbage가 출력될 수 있기 때문에..

읽은 갯수가 i에 반환이 된다. byte[] bs = new byte[10]; 으로 읽지 않은 경우에는 char로 한 바이트씩 반환이 되었지만,

byte[] bs = new byte[10];(Buffer)로 읽었기 때문에 갯수가 반환이 된다. 그래서 아래 예제와 같이 구현해주면 원하는 값이 출력 되는 것을 볼 수 있다.

package java8.stream.inputstream;

import java.io.FileInputStream;
import java.io.IOException;

public class FileInputTest2 {
    public static void main(String[] args) {

        try(FileInputStream fis = new FileInputStream("input2.txt")) {
            int i;
            byte[] bs = new byte[10];
            while ((i = fis.read(bs)) != -1) {
//                for(byte b : bs) {
//                    System.out.print((char)b);
//                }
                for(int k = 0; k < i; k++) {
                    System.out.println((char)bs[k]); // 읽은 갯수만큼 출력, i가 읽은 갯수
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
jeonghyung
ilonetwoth
ree

Buffer을 쓸 때, Garbage가 나올 수 있는 것을 유의하며 써야 좋을 것 같다.

 

FileOutputStream 예제 

txt 파일을 따로 생성하지 않아도 65, 66, 67 아스키코드를 읽어 'output.txt' 파일에 A,B,C가 작성되어 파일이 자동 생성되는 것을 볼 수 있다.

try(FileOutputStream fos = new FileOutputStream("output.txt", true))

뒤에 true를 붙이면 Append가 되어서 'output.txt'에 ABCABC로 계속 이어져서 쓰이게 된다.

 

FileOutputStream & FileInputStream 예제

package java8.stream.outputstream;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputTest2 {
    public static void main(String[] args) {

        byte[] bs = new byte[26];
        byte data = 65;

        for(int i = 0; i <bs.length; i++) {
            bs[i] = data;
            data++;
        }

        try(FileOutputStream fos = new FileOutputStream("alpha.txt", true);
            FileInputStream fis = new FileInputStream("alpha.txt")) {

            fos.write(bs);
            int ch;
            while((ch = fis.read()) != -1) {  // 하나씩 읽음
                System.out.print((char)ch);
            }

        }catch (IOException e) {
            System.out.println(e);
        }
    }
}
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ

입출력 스트림

 

입출력 스트림

입출력 스트림이란? 네트워크에서 자료의 흐름이 물과 같다는 의미에서 유래 다양한 입출력 장치에 독립적으로 일관성 있는 입출력 방식제공 입출력이 구현되는 곳에서는 모두 I/O 스트림을 사

junghyungil.tistory.com

바이트 단위 입출력 스트림

 

바이트 단위 입출력 스트림

바이트 단위 스트림 InputStream : 바이트 단위 입력 스트림 최상위 클래스 OutPutStream : 바이트 단위 출력 스트림 최상위 클래스 추상 메서드를 포함한 추상 클래스로 하위 클래스가 구현하여 사용

junghyungil.tistory.com

문자 단위 입출력 스트림

 

문자 단위 입출력 스트림

문자 단위 스트림 Reader : 문자 단위로 읽는 최상위 스트림 Writer : 문자 단위로 쓰는 최상위 스트림 추상 메서드를 포함한 추상 클래스로 하위 클래스가 상속받아 구현 하위클래스 스트림 클래스

junghyungil.tistory.com

보조스트림

 

보조 스트림

보조스트림 - 실제 읽고 쓰는 스트림이 아닌 보조적인 기능을 추가하는 스트림 - FilterInputStream과 FilterOutputStream이 보조스트림의 상위 클래스 생성자의 매개 변수로 또 다른 스트림을 가짐 생성자

junghyungil.tistory.com

 

 

728x90
반응형
Comments