본문 바로가기
Programming/Java

[자바/Java] 파일 I/O - Data 입출력

by 코딩하는 랄로 2023. 10. 18.
728x90

https://codingralro.tistory.com/entry/%EC%9E%90%EB%B0%94Java-%ED%8C%8C%EC%9D%BC-IO-%EA%B8%B0%EB%B3%B8

 

[자바/Java] 파일 I/O

파일 입출력(I/O) 키보드에서 값을 입력(Scanner) 받고, 콘솔 창에 값을 출력(System.out.println)하는 과정은 익숙하다. 그렇다면 파일에서 값을 읽어오고(입력) 저장(출력)하려면 어떻게 해야 할까? 파일

codingralro.tistory.com

 

Data 입출력

이전에 배웠던 File I/O(위의 링크 참조)는 직접적으로 파일에 스트림을 연결하여 읽고 쓰는 클래스에 대해 다룬다. 이러한 클래스들은 바이트 기반, 문자 기반 스트림으로 문자 또는 바이트 형식으로만 읽고 쓰는것이 가능하다.

 

그렇기 때문에 숫자 데이터를 읽어와야 하는 경우에는, 바이트 또는 문자 데이터로 읽어온 다음에 숫자 타입으로 변환하는 과정을 거쳐야 하는 것이다.

 

매번 숫자 데이터로 변환을 해주는 과정은 코드를 길어지게 하고 복잡하게 하기 때문에 자바에서는 DataInptStream, DataOutputStream 을 통해 기본 타입(primitive type)의 데이터를 읽고 쓸 수 있게 해준다.

 

 

DataInputStream/DataOutputStream

DataInputStream과 DataOutputSteam은 스스로 파일에 읽고 쓸 수 없는 객체이기 때문에 FileInputStream, FileOutputStream을 연결하여 사용하여야 한다.(tip! class명에 File이라고 붙어야 직접 파일을 읽고 쓸 수 있음)

public class Main {
    public static void main(String[] args) {
		
        try (
            //.bin : binary file, 이진 텍스트 파일
            OutputStream out = new FileOutputStream("temp/data.bin");
            DataOutputStream dout = new DataOutputStream(out);
            InputStream in = new FileInputStream("temp/data.bin");
            DataInputStream din = new DataInputStream(in);
        ){
        
        }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

파일 입출력 스트림 객체를 생성한 뒤 해당 객체를 데이터 입출력 스트림의 매개변수로 넘겨주면 데이터 입출력 객체를 사용하여 파일을 읽고 쓰는 것이 가능해진다.

 

 

메소드

데이터 입출력 객체 또한 read 또는 write 메소드를 사용한다.(이 외에 추가적인 메소드도 있지만 주로 read or write를 사용) 또한, 데이터 입출력 객체는 기본 타입을 위한 입출력 객체이기 때문에 해당 메소드의 기본 타입을 명시한 메소드를 가진다.

 

write()

메소드명 내용
writeShort(int v) 매개변수  v로 부터 2byte만 파일에 write
writeByte(int v) 매개변수  v로 부터 1byte만 파일에 write
writeBoolean(boolean v) boolean 값 v를 파일에 write
writeInt(int v) 매개변수  v로 부터 마지막 4byte만 파일에 write
writeChar(int v) 매개변수  v로 부터 마지막 2byte만 파일에 write
writeDouble(double v) double 값 v를 파일에 write
writeFloat(float v) float 값 v를 파일에 write
writeLong(long v) long 값 v를 파일에 write

 

read()

메소드명 내용
readShort() 2byte를 read
read Byte() 1byte를 read
read Boolean() 1byte를 read -> 0 : flase / 1 : true
read Int() 4byte를 read
read Char() 2byte를 read
read Double() 8byte를 read
read Float() 4byte를 read
read Long() 8byte를 read

 

 

사용 예제

public class Main {

	public static void main(String[] args) {

        try (
            OutputStream out = new FileOutputStream("temp/data.bin");
            DataOutputStream dout = new DataOutputStream(out);
            InputStream in = new FileInputStream("temp/data.bin");
            DataInputStream din = new DataInputStream(in);
        ){
            //쓰기
            dout.writeBoolean(true);  // 1 byte
            dout.writeInt(100);   // 4 byte
            dout.writeDouble(3.14);  // 8 byte
            dout.writeChar('A');   // 2 byte

            // 읽기
            boolean b = din.readBoolean();
            int num1 = din.readInt();
            double num2 = din.readDouble();
            char ch = din.readChar();

            System.out.println("boolean: " + b);
            System.out.println("int: " + num1);
            System.out.println("double: " + num2);
            System.out.println("char: " + ch);

        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
		
	}

}

 

데이터 입출력에 대해서 더 자세하게 이해하기 위해서는 해당 타입이 byte를 어느 정도 할당 받고 byte에 어떤식으로 저장되는지를 알아야 한다.

 

이를 위해서 bin파일이 아닌 txt파일에 스트림을 연결하면 이해하기 편하다. 만약 txt 파일에 77을 저장하면 어떻게 저장이 될까?

public class Main {

	public static void main(String[] args) {

        try (
            OutputStream out = new FileOutputStream("temp/data.txt");
            DataOutputStream dout = new DataOutputStream(out);
            InputStream in = new FileInputStream("temp/data.txt");
            DataInputStream din = new DataInputStream(in);
        ){
            //쓰기
            dout.writeInt(77);   //"   M" 으로 저장

        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
		
	}

}

해당 코드를 돌려보면 data.txt 파일에 "   M"으로 저장된 것을 확인할 수 있다. 그 이유로는 int는 4바이트를 제공받고 77이라는 10진법을 4바이트에 다음과 같이 저장된다.

0000 0000 0000 0000 0000 0000 0100 1101

이렇게 저장된 4바이트가 byte별로 텍스트 파일에 저장되면 앞에 "0000 0000"은 빈칸으로 "0100 1101(77)"은 M으로 변환되어 "   M"으로 저장되는 것이다.

 

반대로 "   M"을 readInt하게 되면 77이라는 값을 얻을 수 있다.

728x90