22 Mayıs 2011 Pazar

Apache Commons IO Kütüphanesi

Apache Yazılım Derneği'nin Java'da sık karşılaşılan, JDK tarafından sağlanan sınıflarla yaparsanız "bin dereden su getirmeye" benzeyen görevleri, daha kolay biçimde gerçekleştirmenizi sağlayan araçları bir araya getirdiği Commons adında bir projesi var.

Bu yazıda bu projenin giriş çıkış işlemleri üzerine yoğunlaşan IO kütüphanesini inceliyoruz.Kütüphaneyi buradan indirebilirsiniz. commons-io-2.0.1.jar dosyasını projenizin classpath'ına eklemeniz yeterli.

Bu jar'ın içindeki bazı önemli sınıfları inceleyelim.

IOUtils sınıfı okuma, yazma ve kopyalama işlemleri için bazı yardımcı metodlar barındırır. Bu metodlar InputStream, OutputStream, Reader ve Writer nesneleri üzerinde çalışır.

Örneğin çok sık karşılaşılan bir işlem olan "herhangi bir InputStream'dan gelen verilere String formatında erişme" yi JDK sınıflarıyla şu şekilde gerçeklersiniz:

InputStream in = new URL( "URL-HERE" ).openStream();
 try {
   InputStreamReader inR = new InputStreamReader( in );
   BufferedReader buf = new BufferedReader( inR );
   String line;
   while ( ( line = buf.readLine() ) != null ) {
     System.out.println( line );
   }
 } finally {
   in.close();
 }

Ancak IOUtils sınıfını kullanarak, bu işlemi çok daha basit bir şekilde halledebilirsiniz:

InputStream in = new URL( "URL-HERE" ).openStream();
 try {
   System.out.println( IOUtils.toString( in ) );
 } finally {
   IOUtils.closeQuietly(in);
 }


Buradaki
IOUtils.toString( in );

metodu herhangi bir InputStream'i String olarak döner. Biz burada URL'den gelen bir akış(stream) kullandık. Ama sadece bununla sınırlı değilsiniz. InputStream dönen herhangi bir kaynak kullanabilirsiniz. Örneğin; File nesneleri, BufferedReader'lar...

FileUtils sınıfı File nesneleriyle birlikte kullanabileceğiniz çeşitli metodlar içerir. Bu metodları kullanarak dosyalarla okuma, yazma, kopyalama ve karşılaştırma işlemlerini çok daha kolay yapabilirsiniz. Örneğin; bir dosyayı satır satır okumak için şu kod parçasını kullanabilirsiniz.

File file = new File("/commons/io/project.properties");
List lines = FileUtils.readLines(file, "UTF-8");

FilenameUtils sınıfı da File nesneleri kullanma zorunluluğunu ortadan kaldırarak, dosya adlarıyla uğraşmanın daha basit yollarını sunar. Bu sınıf genelde Linux/Windows sistemler arası uyumluluğu sağlamak için kullanılır. Örneğin bir dosya adındaki çift noktaları kaldırmak için şu kodu kullanabilirsiniz.

String filename = "C:/commons/io/../lang/project.xml";
String normalized = FilenameUtils.normalize(filename);
// çıktı: "C:/commons/lang/project.xml"

FileSystemUtils sınıfı işletim sistemindeki dosya sistemi yapısı ilgili işlemler yapmak için JDK'da bulunmayan bazı yardımcı metodlar içerir. Örneğin: C diskindeki boş alan miktarını öğrenmek için;

long freeSpace = FileSystemUtils.freeSpace("C:/");

LineIterator sınıfıyla metin tabanlı bir dosyanın satırlarına kolayca tek tek ulaşabilirsiniz. LineIterator kurucu ile oluşturulabileceği gibi IOUtils ve FileUtils sınıfları üzerinden fabrika meodlarıyla da oluşturulabilir. Örnek kullanımı:

LineIterator it = FileUtils.lineIterator(file, "UTF-8");
 try {
   while (it.hasNext()) {
     String line = it.nextLine();
     /// do something with line
   }
 } finally {
   LineIterator.closeQuietly(iterator);
 }

Hazır Dosya Filtreleri
org.apache.commons.io.filefilter paketinde JDK'nın java.io.FileFilter ve java.io.FilenameFilter. interface'lerini birleştirip, bunlara daha gelişmiş ek özellikler katan IOFileFilter interface'i bulunur. Pakette ayrıca bu interface'in hazır örnekleri de mevcuttur. Bu filtreleri örneğin bir FileDialog nesnesinde sadece belli tür dosyaları göstermek için kullanabilirsiniz. Hazır filtrelerden bazıları şunlardır. Not: Sınıf isimleri yeterince açıklayıcı olduğu için, ayrıca açıklamalarını yazmadım.


DirectoryFilter, PrefixFileFilter, SuffixFileFilter, NameFileFilter, WildcardFileFilter, AgeFileFilter, SizeFileFilter, TrueFileFilter, FalseFileFilter, NotFileFilter, AndFileFilter, OrFileFilter

Örneğin, geçerli dizindeki, dizin olmayan, "A" ile başlayıp,  ".java" veya ".class" ile biten dosyaları listelemek için:

File dir = new File(".");
  String[] files = dir.list( 
    new AndFileFilter(
      new AndFileFilter(
        new PrefixFileFilter("A"),
        new OrFileFilter(
          new SuffixFileFilter(".class"),
          new SuffixFileFilter(".java")
        )
      ),
      new NotFileFilter(
        new DirectoryFileFilter()
      )
    )
  );
  for ( int i=0; i<files.length; i++ ) {
    System.out.println(files[i]);
  }


Bu pakette ayrıca FileFilterUtils sınıfı da mevcuttur. Bu sınıf az önce saydığın filtre sınıflarını import etmeden statik alanlar üzerinden çok daha kolay çağırmayı sağlar. Az önceki örnek bu sınıf yardımıyla tekrar yazılırsa şu hale dönüşür:

File dir = new File(".");
  String[] files = dir.list( 
    FileFilterUtils.andFileFilter(
      FileFilterUtils.andFileFilter(
        FileFilterUtils.prefixFileFilter("A"),
        FileFilterUtils.orFileFilter(
          FileFilterUtils.suffixFileFilter(".class"),
          FileFilterUtils.suffixFileFilter(".java")
        )
      ),
      FileFilterUtils.notFileFilter(
        FileFilterUtils.directoryFileFilter()
      )
    )
  );
  for ( int i=0; i<files.length; i++ ) {
    System.out.println(files[i]);
  }

Dosya Karşılaştırıcıları
org.apache.commons.io.comparator paketi java.io.File sınıfı için java.util.Comparator interface'inin birkaç hazır örneğini içerir. Bu karşılaştırıcılar dosya listelerini veya dizilerini sıralamak için kullanılabilir.

Bütün karşılaştırıcılar kendi özelliklerine göre uygun sort(File...) ve sort(List) metodlarını içerir. Örneğin, bir dizindeki dosyaları dosya adına göre sıralamak için;

File[] files = dir.listFiles();
NameFileComparator.NAME_COMPARATOR.sort(files);

Aynı işlemi tek satırda da yapabilirsiniz:

File[] files = NameFileComparator.NAME_COMPARATOR.sort(dir.listFiles());
  

CompositeFileComparator sınıfı karşılaştırma ve sıralama işlemini birkaç karşılaştırıcıyı birleştirerek yapabilir. Örneğin dosyaları önce türüne sonra da adına göre sıralamak için;

CompositeFileComparator comparator =new CompositeFileComparator(
DirectoryFileComparator.DIRECTORY_COMPARATOR,NameFileComparator.NAME_COMPARATOR);
File[] files = dir.listFiles();
comparator.sort(files); 


Akışlar(Stream)
org.apache.commons.io.input ve org.apache.commons.io.output paketleri akışların kullanışlı birkaç örneğini içerir. Bazıları;

  • Null output stream - Kendisine gönderilen bütün veriyi emer (yok eder).
  • Tee output stream - Çıktıyı tek akış yerine iki akışa yönlendirir.
  • Byte array output stream - JDK'daki abisinin daha hızlısı
  • Counting streams - Aldığı veriyi byte olarak sayan akış
  • Proxy streams - Proxy tasarım desenini uygular ve akışı uygun metoda yönlendirir.
  • Lockable writer
Bu yazıda Apache Commons'un IO kütüphanesini tanıtmaya çalıştım. Sınıflar ve kullanımları hakkında daha detaylı bilgiyi kütüphanenin Javadoc'unda bulabilirsiniz.

Hiç yorum yok:

Yorum Gönder