- Published on
nio 패키지의 Path를 사용합시다!
- 글쓴이
File
객체의 사용과 한계
Java에서 파일 경로를 처리하는 방법: 자바 코드를 작성하다가 파일 경로를 다루는 경우는 상당히 흔하게 겪는 일이다. 보통은 이럴 때 File
객체를 사용해서 코드를 작성한다.
예를 들어, 파일의 메시지 ID를 추출하는 코드가 있다. 아래 코드는 맥 환경에서 잘 동작한다.
private void loadData() throws IOException
{
File dir = new File(CONFIG_PATH + "/data" );
assertTrue(dir.isDirectory());
File[] list = dir.listFiles();
if( null == list )
return;
for( File f: list )
{
String dataId = extractMessageID( f );
String data = readFile( f );
dataRepo.put( dataId, data );
}
assertEquals( dataRepo.size(), list.length );
}
문제점
위 예시 코드는 맥북에서 잘 작동하지만 윈도우에서 돌려보면 에러가 발생한다.
왜일까? 바로 Windows와 Unix 기반 운영체제에서 file.separator
의 값이 다르기 때문이다. File.getPath()
메소드는 운영체제에 따라 반환값이 달라진다.
윈도우에서는 경로를 표현할 때 \
를 사용하고, 맥과 리눅스에서는 /
를 사용한다.
즉, 운영체제마다 파일 경로를 표현하는 방식이 다르기 때문에 문제가 발생한다.
방법 1 : 한줄로 해결하기
그럼 이런 문제를 어떻게 해결해야 할까? 첫 번째 방법은 System.getProperty("file.separator")
를 사용하는 것이다.
이는 현재 운영체제의 파일 경로 구분자를 반환하는 메서드로, 아래와 같이 수정하여 사용할 수 있다.
private void loadData() throws IOException
{
File dir = new File(CONFIG_PATH + System.getProperty("file.separator") +"data" );
assertTrue(dir.isDirectory());
File[] list = dir.listFiles();
if( null == list )
return;
for( File f: list )
{
String dataId = extractMessageID( f );
String data = readFile( f );
dataRepo.put( dataId, data );
}
assertEquals( dataRepo.size(), list.length );
}
java.nio.file.Path
사용하기
방법 2 : 두 번째 방법은 java.nio.file.Path
를 사용하는 것이다.
nio 패키지의 Path를 사용하면 운영체제에 따른 파일 경로 구분자 식별 문제를 해결할 수 있다.
private void loadData() throws IOException
{
Path dir = Paths.get(CONFIG_PATH,"data");
assertTrue(Files.isDirectory(dir));
DirectoryStream<Path> paths = Files.newDirectoryStream(dir);
int pathsLength = 0;
if( null == paths )
return;
for( Path path: paths )
{
logger.info( "FILE : [{}]", path.normalize() );
logger.info( "DATA : [{}]", readFile(path) );
logger.info( "ID : [{}]", extractMessageID( path ) );
String dataId = extractMessageID( path );
String data = readFile( path );
dataRepo.put( dataId, data );
pathsLength++;
}
assertEquals( dataRepo.size(), pathsLength );
}
Path
의 장점
Path
객체는File
과 상호호환된다. 즉,File
객체를Path
객체로, 그 반대도 가능하다.Path
를 사용하면 운영체제마다 파일 경로 구분자를 식별할 필요가 없다. 이는 코드의 가독성을 높이고 버그를 줄일 수 있다.Path
는File
보다 풍부한 에러 처리와 메시지를 제공한다. 오류 상황을 더 세세하게 다룰 수 있다.- 또한,
Path
객체는File
객체보다 더 많은 메서드를 제공한다.
결론
파일 경로를 다룰 때는 운영체제에 따른 차이를 고려하는 것이 중요하다.
File
객체 대신 Path
객체를 사용하면 이러한 문제를 효과적으로 해결할 수 있다.