본문 바로가기

Java/Base

[JAVA] 파일 입출력

FileInputSteam

 

InputStream을 상속받는 Byte 기반의 클래스이다.

 

다음 txt파일을 불러오는 과정이다.

 

test1.txt

 

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

public class FileInputStreamTest {
    public static void main(String[] args) {
        try {
            FileInputStream fin = new FileInputStream("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test1.txt");
            int data;
            while((data = fin.read()) != -1) {
                System.out.print((char)data);
            }
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

 

 

결과는 다음과 같다.

 

 

영어는 정상적으로 출력된 반면, 한글은 전부 깨져있는 것을 확인할 수 있다.

앞서 말했듯이 FileInputStream은 byte기반의 클래스이다.

그리고 한글은 한 자당 2Byte의 크기를 가진다.

즉, 이 클래스로는 한글을 정상적으로 읽어들일 수 없다는 것이다.

한글을 읽기 위해선 Reader와 Writer를 사용하여야한다.

 

FileOutputSteam

 

InputStream으로 읽어온 데이터는 ASCII코드에 맞는 int값으로 저장된다.

출력할 때에는 char의 형변환을 이용하였지만, 다른 파일에 복사해넣을 때에는 바로 작성할 수 있다.

 

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

public class FileInputStreamTest {
    public static void main(String[] args) {
        try {
            FileInputStream fin = new FileInputStream("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test1.txt");
            FileOutputStream fout = new FileOutputStream("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test2.txt");
            int data;
            while((data = fin.read()) != -1) {
                System.out.print((char)data);
                fout.write(data);
            }
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

 

 

 

실행시키기 전의 파일이다.

 

 

"test2"라는 이름의 txt파일이 새로 작성되었다.

 

Buffered(Input/Output)Stream

 

Stream은 Byte단위로 실행되기 때문에 입출력을 하는데에 있어서 소요되는 시간이 길다.

이를 해결하기 위해선 버퍼를 이용해야 한다.

 

Read -> 버퍼에 채워진 데이터를 읽는 동안 InputStream이 File에서 새데이터를 가져와 버퍼를 채워놓는다.

Write -> 버퍼에 데이터를 채우면 OutputStream이 File에 출력한다.

 

BufferedStream은 자체적으로 입출력을 행할 수 없기 때문에 Input/OutputStream을 생성자의 매개변수로 받아야한다.

 

import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;

public class FileInputStreamTest {
    public static void main(String[] args) {
        try {
            FileInputStream fin = new FileInputStream("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test1.txt");
            BufferedInputStream bin = new BufferedInputStream(fin);

            FileOutputStream fout = new FileOutputStream("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test2.txt");
            BufferedOutputStream bout = new BufferedOutputStream(fout);

            int data;
            while((data = bin.read()) != -1) {
                System.out.print((char)data);
                bout.write(data);
            }
            bout.close();
            
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

 

추가적으로 Buffer를 사용하였기에 close() 메소드를 이용해 메모리를 해제해주어야한다.

 

Character 기반의 Stream

 

Character 기반의 Stream은 Reader와 Writer를 상속받는다.

또한, Byte기반이 아니기 때문에 2Byte의 한글도 입력받을 수 있다.

 

import java.io.FileReader;
import java.io.FileWriter;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileReaderNWriterTest {
    public static void main(String[] args) {
        try {
            FileReader fin1 = new FileReader("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test1.txt");
            FileWriter fout1 = new FileWriter("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test2.txt");

            int data;
            while((data = fin1.read()) != -1) {
                System.out.print((char)data);
                fout1.write(data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

 

이번에는 한글도 제대로 출력된 것을 확인할 수 있다.

 

Buffered(Reader/Writer)

 

마찬가지로 버퍼를 사용하면 좀더 빠른 작업 수행이 가능하다.

 

import java.io.FileReader;
import java.io.FileWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.BufferedWriter;

public class FileReaderNWriterTest {
    public static void main(String[] args) {
        try {
            FileReader fin1 = new FileReader("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test1.txt");
            BufferedReader bin1 = new BufferedReader(fin1);
            FileWriter fout1 = new FileWriter("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test2.txt");
            BufferedWriter bout1 = new BufferedWriter(fout1);

            int data;
            while((data = fin1.read()) != -1) {
                System.out.print((char)data);
                bout1.write(data);
            }
            bout1.close();

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

 

IOException

 

자바는 입출력과 관련된 예외에 대해 민감하게 다룬다.

print(), println(), printf()는 자체적으로 예외처리가 되어있으니, 이를 제외하고 모든 입출력 메소드에서는 항상 예외처리를 해주어야만 한다.

위의 BufferedWriter에서 예외처리를 하지 않는다면,

 

import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.BufferedWriter;

public class FileReaderNWriterTest {
    public static void main(String[] args) {
        FileReader fin1 = new FileReader("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test1.txt");
        BufferedReader bin1 = new BufferedReader(fin1);
        FileWriter fout1 = new FileWriter("C:\\Users\\wjdck\\IdeaProjects\\TestJava\\src\\test2.txt");
        BufferedWriter bout1 = new BufferedWriter(fout1);

        int data;
        while((data = fin1.read()) != -1) {
            System.out.print((char)data);
            bout1.write(data);
        }
        bout1.close();
    }
}

 

 

이러한 에러를 확인할 수 있다.

말그대로 IOException 예외처리가 안되어 있기에 발생하는 에러이다.

'Java > Base' 카테고리의 다른 글

[JAVA] 예외처리  (0) 2023.09.11
[JAVA] 리스트  (0) 2023.09.07
[JAVA] 키보드 입력  (0) 2023.09.06
[JAVA] 배열  (0) 2023.09.05
[JAVA] 생성자  (0) 2023.08.17