자바를 사용해 파일 입출력 기능을 구현하는 과정에서 여러 어려움에 부딪히며 많은 시간을 투자하게 되었습니다. 그 과정에서 시도했지만 결국 사용하지 않은 방법들도 있었는데, 이를 정리해 기록해 두기로 했습니다. 나중에 자바로 파일 입출력을 다시 다뤄야 할 상황이 온다면, 이 글을 참고해 좀 더 수월하게 접근할 수 있기를 바라며 작성하게 되었습니다.
이번 글에서는 자바를 활용하여 src/resources/test.md 파일을 입출력의 예제로 사용하며, 구현 과정에서 배운 점과 고려해야 할 부분들을 공유해보려고 합니다.
Java에서 resources 패키지는 주로 애플리케이션에서 사용하는 정적 파일들을 관리하는 디렉토리로, 외부 설정 파일, 텍스트 파일, 이미지, 프로퍼티 파일, XML 파일 등 다양한 리소스 파일을 포함한다. Java 애플리케이션은 이러한 리소스를 파일 경로 대신 클래스패스를 통해 접근하여, 경로 문제 없이 안정적으로 파일을 로드할 수 있다. 자바에서는 주로 src/main/resources 경로에 위치한 리소스를 관리한다.

Java를 처음 시작할 때 IDE(인텔리제이)에서 왼쪽에 노란색으로 표시된 resources 패키지를 본 적이 있을지 모르겠다. 주로 스프링 프로젝트를 실행할 때 자주 보이는데, Java만으로 프로젝트를 열어본 적이 별로 없어서 그동안 크게 신경 쓰지 않았던 것 같다. 처음 Java를 배울 때는 src 폴더에 더 신경 쓰느라 resources에는 별다른 관심을 두지 않았던 것 같다. 😊
이번에 진행하려는 작업은 src/resources/test.md에 있는 파일 내용을 프로그램 내에서 불러와 활용하는 것이다. 그렇다면, 파일을 읽어오는 방법을 생각해봐야겠다. Java에서는 여러 가지 방법으로 파일을 읽어올 수 있는데, BufferedReader나 Files 클래스의 메서드를 사용해 간편하게 파일 내용을 불러올 수 있다.
resources 패키지에서 파일을 다루는 방식resources 패키지의 파일을 직접 파일 경로로 접근하는 대신, 클래스패스를 통해 접근한다. 클래스패스는 컴파일된 클래스 파일과 리소스 파일을 포함하는 경로이며, 이를 통해 애플리케이션이 파일 위치에 종속되지 않게 된다.ClassLoader나 Class의 메서드를 이용한다.
getResourceAsStream 메서드를 사용하여 클래스패스에 있는 파일을 InputStream 형태로 읽어온다. 이 방식으로 리소스 파일을 읽으면 운영체제와 무관하게 파일을 처리할 수 있다.Path와 Files 클래스 활용Path 및 Files 클래스를 이용해 리소스를 읽을 수도 있다. 이 경우 파일을 바이트 또는 문자열로 읽거나 파일 경로를 확인하는 기능을 사용할 수 있다.
Properties 클래스 활용Properties 클래스를 자주 사용한다. 주로 .properties 파일을 통해 애플리케이션의 설정 정보를 저장하고, 실행 중에 필요한 설정값을 로드하여 사용할 수 있다.
(spring 프로젝트를 진행할 때, 관성적으로 properties를 지우고 application.yml 을 사용했었는데 어떻게 다르고 왜 사용했는지 기억이 잘 나지 않는다. 이것도 다시 학습해봐야겠다.).
resources 패키지에 파일 추가 및 활용 시 주의 사항resources 디렉토리에 파일을 추가할 때는 경로가 정확한지 확인해야 한다. 예를 들어, 서브 디렉토리에 파일을 저장했다면 getResourceAsStream("subdir/파일명.txt")처럼 경로를 포함해야 한다.resources 폴더는 JAR 파일로 패키징되므로, 리소스 접근 방식은 파일 시스템의 위치와 상관없이 클래스패스에서 로드해야 한다.자, 이렇게 해서 파일을 불러오는 방법을 알아보았다. 이제 이 파일 데이터를 활용하고, 변경 사항이 생기면 저장도 해야겠다. 그런데 콘솔에서는 저장된 것처럼 보이는데, 실제로 .md 파일을 확인해 보면 파일이 변경되지 않네요. 이게 무슨 상황일까? 파일이 변경되지 않은 걸로 보아 캐시에 저장된 값을 불러오는 걸까?
파일 데이터를 변경해 보면 수정된 값이 불러와지긴 하지만, 다시 저장이 되지 않는 상황이다. 이 문제를 해결하기 위해 여러 자료를 찾아보았지만, 정확하게 설명해 둔 글이 많지 않았다. 터미널에서 파일 권한을 확인해 보기도 했다.
이런 상황을 경험하신 적이 있으신가요?
알아보니, Java 애플리케이션에서 resources 패키지에 포함된 파일은 일반적으로 수정이 불가능하다. 이는 주로 다음과 같은 이유 때문이다:
resources 디렉토리는 애플리케이션이 컴파일되고 배포될 때, JAR 파일로 패키징된다. JAR 파일은 압축된 상태로 포함되며, 이로 인해 클래스패스 내의 리소스는 읽기 전용으로 동작한다.ClassLoader를 통해 resources의 파일에 접근할 때 InputStream을 반환하기 때문에 읽기 전용 방식으로 접근하게 됩다.resources 디렉토리의 파일은 애플리케이션 외부의 파일 시스템이 아닌 클래스패스 내부에서 관리된다. 클래스패스 내부에 있는 리소스를 수정하려면 파일 시스템의 파일처럼 접근할 수 없기 때문에 일반적인 파일 쓰기 작업이 제한된다.그렇다면 파일을 불러와서 수정을하고 저장을 어떻게 할까,,
resources 파일을 수정하는 방법만약 애플리케이션 실행 중에 특정 설정 파일을 수정해야 하는 경우에는 다음과 같은 방법을 사용할 수 있다:
resources에 포함된 설정 파일 대신 파일 시스템 외부의 특정 디렉토리에 설정 파일을 저장하고 수정할 수 있겠다.결론적으로는 resources 파일으로 부터 값을 읽어왔으면 변경하고 다시 저장은 어렵겠다. 그러면 어떻게..?
resources 하위에서 읽어 오지만, 최초 실행 이후에는 다른 파일에서 읽고, 쓰기를 진행한다.resources 에서 값을 불러오지만 그 뒤에 진행되거나 프로그램이 재시작 되면 다른 파일 값을 가지고 읽고, 쓰기 때문에 resources 파일은 보존되고 수정도 가능한 이점을 얻을 수 있다.

결국 요구사항과 테스트 코드에 맞추어 이 방법을 사용하지 않고, 프로그램이 실행될 때만 수정 및 반영이 가능하면 된다는 결론에 도달했다. 활용할 수는 없었지만, 이번 기회를 통해 resources의 특징을 알게 되었고, properties와 yml의 차이에 대한 이해가 부족함을 다시 한번 깨달으며 배움의 기회가 되었다. 이 글이 비슷한 어려움을 겪는 분들께 조금이나마 도움이 되었으면 좋겠다.