아파치 소프트웨어 재단에서 제공하는 자바 기반의 오픈소스 중 Commons IO 라이브러리가 있습니다. 얼마전 고객과의 미팅을 통해 요구사항을 파악하던 중.. 예상치 못한 기능을 요청받았고 이 기능을 기존 시스템에 추가하려면 상당한 코딩을 해야 할 상황에서 요긴하게 사용한 라이브러리 중에 하나입니다.
이 Commons IO 라이브러리는 기존의 JDK에서 제공하는 클래스들에 대해서 자주 사용하는(Commons 한) 기능들을 클래스화 해 놓은 것으로 이해하면 크게 틀리지 않습니다. 물론 기존의 JDK에서 제공되는 클래스들에 대해 보다 개선된 클래스를 제공하고 있기는 하지만 말입니다.
이 글은 Commons IO 라이브러리의 공식 홈페이지에서 매우 간단한 예제를 통해 해당 라이브러리를 소개하고 있는 글을 한글로 정리한 것입니다. 사실.. 제가 이 Commons IO를 직접 사용한것이 아니고 대용량 파일을 서버로 업로드하는 기능을 제공하는 아파치 소프트웨어 재단에서 제공하는 또 다른 Commons Fileupload 라이브러리에서 이 Commons IO 라이브러리를 사용하는 것을 보고 관심을 가져 보게 되었고 실제 기본적인 내용을 살펴보게 되었습니다.
먼저 해당 URL에 대한 데이터 전체를 문자열로 가져오는 예입니다.
InputStream in = null; try { in = new URL("href='http://www.google.co.kr").openStream(); System.out.println(IOUtils.toString(in)); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(in); }
JDK에서 제공하는 기본적인 클래스들을 이용해 위의 코드를 작성했다면 더 긴 코드가 필요했을테고.. 코드가 길다는 것은 그만큼 문제가 발생할 가능성이 높다는 것입니다. 아파치의 Commons IO는 수많은 프로그램에서 사용된 검증된 라이브러리입니다.
다음은 텍스트 파일을 라인별로 읽어 List 컨테이너로 파싱하는 예입니다.
File file = new File("c:/text.txt"); try { List lines = FileUtils.readLines(file, "utf-8"); Iterator it = lines.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } catch (IOException e) { e.printStackTrace(); }
매우 직관적이고 심플합니다.. 하지만 대용량의 텍스트 파일의 경우 모든 데이터를 읽어 하나의 리스트 컨테이너에 집어 넣으니 메모리 문제가 발생할 수 있다는 점을 염두해 둬야 합니다.
다음은 텍스트 파일을 구성하는 라인을 하나 하나 필요할때마다 읽어 처리할 수 있는 예입니다.
File file = new File("c:/text.txt"); LineIterator it = null; try { it = FileUtils.lineIterator(file); while(it.hasNext()) { System.out.println(it.next()); } } catch (IOException e) { e.printStackTrace(); } finally { if(it != null) { LineIterator.closeQuietly(it); } }
다음은 파일 경로를 정규화해주는 코드입니다.
String filename = "c:/commons/io/../../lang/../project.txt"; String normailzed = FilenameUtils.normalize(filename); System.out.println(normailzed);
위 코드의 결과는 c:/project.txt가 됩니다.
그리고 해당 경로에 대한 저장 장치의 가용 용량을 얻는 코드입니다.
try { long freeSpace = FileSystemUtils.freeSpaceKb("c:/"); System.out.println(freeSpace + "kb"); } catch (IOException e) { e.printStackTrace(); }
이 외에도 파일의 복사, Endian 처리, 다양한 응용 스트림 클래스 등을 제공합니다. 이 처럼 일반적으로 많이 사용되는 IO 루틴에 대해서 더 짧은 코드를 통해서, 그리고 검증된 방법을 통해 구현할 수 있는 라이브러리를 사용한다면 원하는 기능을 더욱 빠르고 안정적으로 추가 개발할 수 있습니다. 이러한 라이브러리를 미리 알고 있는 것으로 개발자의 역량은 기술면에서 더 높아질 것입니다.