자바 File 클래스
목차
자바에서 File을 다루는 방법은 여러가지가 있지만 이 포스팅에서는 File 클래스 등을 사용해보겠습니다.
프로그래밍에서 파일은 여러가지 의미를 가지고 있습니다. 우리가 알고 있는 내문서 폴더의 ‘파일’ 이 파일입니다만 입출력 장치를 비롯해 여러가지를 추상화 시키는데 파일을 사용합니다.
파일 챕터에 들어가면 좀 헷갈리는게 I/O 스트림이니 뭐니 또 복잡한 이야기가 나옵니다. 일단 그 내용은 잠시 접어두고 File 을 사용하는 법부터 알아보겠습니다.
예제 File 클래스 테스트
File 클래스는 IOException 과 함께 사용합니다. 파일 자체가 입출력의 추상화입니다. 파일을 저장장치로 알고 있었다면 그것도 맞습니다.
정확히 파일을 정의하면 파일은 데이터가 입력을 받기도 하고 다른 곳으로 출력하기도 하는 가상의 입출력장치입니다. 파일을 이해하려면 이 가상화(virtualization)와 추상화(abstraction)에 대하여 한번 깊이있는 개념을 짚어봐야 합니다.
예를 들어 파일을 모니터에 출력한다고 합니다. 그러면 파일 내용을 메모리에 가져와서 다시 그래픽 카드로 보내고 그래픽카드는 모니터에 출력합니다. 파일의 내용이 텍스트라면 한글자씩 출력하면 너무 느립니다. 그래서 뭉탱이(스트림)을 만들어서 보냅니다. 스트림은 마치 흐르는 강물같이 유연한 것 입니다. File 자체가 스트림의 속성을 가지고 있는 것이죠.
파일에 입력을 받을 때도 마찬가지 입니다. 키보드에서 입력을 받는다면 언제 받을까요? 한글자씩 보내는 것보다 텍스트 한줄을 쓰고 엔터키를 눌렀을 때 보내는게 더 효율적일 겁니다. 키보드의 입력이 아니라 파일과 파일간에 입력이라면 수천 수만개 문자를 보내야할 지도 모릅니다. 이 때 스트림(뭉탱이 흐름)을 만들어 보냅니다.
여기서 스트림이 어떻게 전달되고 있는지 그것까지 이해할 수는 없습니다. 스트림 시스템을 설계한 사람이 알겠죠. 허나 개념은 이해할 수 있습니다. 입력과 출력이 있는 모든 장치를 파일이라고 생각해볼 수 있습니다. 그리고 파일은 스트림으로 전달됩니다. 여전히 어렵죠?
예제부터 보겠습니다.
import java.io.File; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { FileEx fe = new FileEx("aFile.txt"); File myFile = fe.getMyFile(); System.out.println("-- is File? " + myFile.isFile()); System.out.println("-- is Directory? " + myFile.isDirectory()); System.out.println("-- Name? " + myFile.getName()); System.out.println("-- AbsolutePath : " + myFile.getAbsolutePath()); System.out.println("-- Path : " + myFile.getPath()); myFile.deleteOnExit(); } } class FileEx{ File myFile; FileEx(String fileName) throws IOException { myFile = new File(fileName); myFile.createNewFile(); } public File getMyFile() { return myFile; } }
-- is File? true -- is Directory? false -- Name? aFile.txt -- AbsolutePath : D:\Programming\JavaPRJ\smoothiejava\aFile.txt -- Path : aFile.txt
위의 코드는 File 객체를 생성하여 실제 파일을 만들어 보고 테스트를 한 후에 파일을 삭제합니다. File 객체라고 하지만 사실은 파일의 경로(Path)를 통해 파일을 조작합니다.
aFile.txt 는 만들어졌다가 delete 호출로 삭제합니다.
기본 메소드를 사용하면 File 인지 여부 파일의 경로 등의 정보를 꺼낼 수 있습니다.
자바 RandomAccessFile
RandomAccessFile 클래스는 파일 포인터로 임의의 장소에 접근이 가능합니다.
예제를 통해 보겠습니다. RandomAccessFile의 경우 매개변수를 넘겨주면 자동으로 파일을 생성합니다. rw 는 read write 의 약자입니다.
여기서 인스턴스에는 파일포인터가 들어있는데요. 파일포인터를 바이트 단위로 이동시켜서 파일에 접근할 수 있습니다. writeInt 메소드는 텍스트가 아닌 실제 숫자값을 파일에 씁니다. 실제 값은 메모장에서 열어보면 깨진 글자처럼 보입니다.
import java.io.IOException; import java.io.RandomAccessFile; public class Main { public static void main(String[] args) throws IOException { RandomAccessFile randomF = new RandomAccessFile("a.txt", "rw"); System.out.println("4바이트 정수값 입력"); randomF.writeInt(777); System.out.println("File Pointer : " + randomF.getFilePointer()); System.out.println("seek 메소드로 초기화"); randomF.seek(0); System.out.println("File Pointer : " + randomF.getFilePointer()); int myInt = randomF.readInt(); System.out.println("* - 저장된 수를 가져온다 : " + myInt); System.out.println("File Pointer : " + randomF.getFilePointer()); System.out.println("* - UTF 사용하기"); randomF.writeUTF("UTF Hello World!"); System.out.println("File Pointer : " + randomF.getFilePointer()); System.out.println("* - 파일 포인터를 옮겨서 출력한다"); randomF.seek(4); String myUTF = randomF.readUTF(); System.out.println(myUTF); } }
4바이트 정수값 입력 File Pointer : 4 seek 메소드로 초기화 File Pointer : 0 * - 저장된 수를 가져온다 : 777 File Pointer : 4 * - UTF 사용하기 File Pointer : 22 * - 파일 포인터를 옮겨서 출력한다 UTF Hello World!
파일포인터를 조작하는 것은 바이트 계산을 해야하므로 쉬운일은 아닙니다. 자바에서 File 을 취급하는 방법은 여러가지가 있으므로 상황에 따라 적절한 클래스를 선택해서 사용할 수 있도록 합니다.
요약
자바 File 클래스와 RandomAccessFile 클래스로 파일을 만들고 사용하는 약간의 맛을 봤습니다.
파일, 스트림 등 헷갈린 개념이 또 나오기 때문에 충분히 주의하도록 합니다.
자바에서 파일을 사용하면 적절한 Exception처리를 해줘야 컴파일이 됩니다.
참고문서
File I/O 자바 File 클래스 (oracle.com)