Apache Commons IO简介

虽然Google的guava对Java的IO操作进行了一定封装,但是它更偏向于集合、并发和缓存,在实际项目中,我非常喜欢guava,同时我也非常喜欢Apache的一个工具包org.apache.commons.io,这两个工具包提供非常强大的工具能力,能够简化代码逻辑,提高开发效率和质量,是每个Java程序员都应该掌握的工具包。此文简单介绍一下org.apache.commons.io,详细的可参考其API注,此文绝大部分内容翻译自http://www.javacodegeeks.com/2014/10/apache-commons-io-tutorial.html,感兴趣的查看原文,本文源码请移步

Apache Commons IO是Apache开源的一个工具包,其封装了对IO的常见操作,使开发人员只需要少量的代码就能完成大量的IO操作,此文主要介绍如下几个工具类

  • Utility classes
  • Input
  • Output
  • Filters
  • Comparators
  • File Monitor
目前org.apache.commons.io2.4版本并未托管到Maven库,所以需要自行下载然后将下载的commons-io-2.4.jar添加到环境变量中

1、Utils(FileUtils,FilenameUtils,FileSystemUtils)这三个类主要提供了对文件、文件名及文件系统的操作,API非常简单,通过API名称都能知道其作用,

示例如下

 //文件绝对路径
    private static final String EXAMPLE_TXT_PATH =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/commonio.txt";
    //文件父目录
    private static final String PARENT_DIR =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio";

    public static void runExample() throws IOException {
        System.out.println("Utility Classes example...");
        
        
        // FilenameUtils类示例
        //获取完整路径
        System.out.println("Full path of exampleTxt: " +
                FilenameUtils.getFullPath(EXAMPLE_TXT_PATH));
        //获取名称
        System.out.println("Full name of exampleTxt: " +
                FilenameUtils.getName(EXAMPLE_TXT_PATH));
      //获取扩展名
        System.out.println("Extension of exampleTxt: " +
                FilenameUtils.getExtension(EXAMPLE_TXT_PATH));
        
        System.out.println("Base name of exampleTxt: " +
                FilenameUtils.getBaseName(EXAMPLE_TXT_PATH));
        
        
        // FileUtils类示例
        
        // 通过FileUtils.getFile(String)创建File对象,然后根据FileUtils.lineIterator(File)
        //获取行迭代器
        File exampleFile = FileUtils.getFile(EXAMPLE_TXT_PATH);
        LineIterator iter = FileUtils.lineIterator(exampleFile);
        
        System.out.println("Contents of exampleTxt...");
        while (iter.hasNext()) {
            System.out.println("\t" + iter.next());
        }
        iter.close();
        
        // 目录是否已经包含文件
        File parent = FileUtils.getFile(PARENT_DIR);
        System.out.println("Parent directory contains exampleTxt file: " +
                FileUtils.directoryContains(parent, exampleFile));
        
        
        // IOCase类示例
        
        String str1 = "This is a new String.";
        String str2 = "This is another new String, yes!";
        
        System.out.println("Ends with string (case sensitive): " +
                IOCase.SENSITIVE.checkEndsWith(str1, "string."));
        System.out.println("Ends with string (case insensitive): " +
                IOCase.INSENSITIVE.checkEndsWith(str1, "string."));
        
        System.out.println("String equality: " +
                IOCase.SENSITIVE.checkEquals(str1, str2));
        
        
        // FileSystemUtils类示例
        System.out.println("Free disk space (in KB): " + FileSystemUtils.freeSpaceKb("/Users"));
        System.out.println("Free disk space (in MB): " + FileSystemUtils.freeSpaceKb("/Users") / 1024);
    }

2、InputStream,其提供了XmlStreamReader工具类,能够获取xml的文件编码等操作,

示例如下

private static final String XML_PATH =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/test.xml";
    
    public static void runExample() {
        System.out.println("Input example...");
        XmlStreamReader xmlReader = null;
        try {
            
            // XmlStreamReader:读取一个xml文件,提供了过去文件编码API
            File xml = FileUtils.getFile(XML_PATH);
            xmlReader = new XmlStreamReader(xml);
            System.out.println("XML encoding: " + xmlReader.getEncoding());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try { xmlReader.close(); }
            catch (IOException e) { e.printStackTrace(); }
        }
    }
3、Output,其提供的TeeInputStream,TeeOutputStream类能将输入流快速拷贝到输出流中

private static final String INPUT = "This should go to the output.";

    public static void runExample() {
        System.out.println("Output example...");
        TeeInputStream tee=null;
        TeeInputStream teeIn = null;
        TeeOutputStream teeOut = null;
        
        try {
            //TeeInputStream能将输入流快速拷贝到输出流中
            ByteArrayInputStream in = new ByteArrayInputStream(INPUT.getBytes("US-ASCII"));
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            tee = new TeeInputStream(in, out, true);
            tee.read(new byte[INPUT.length()]);
            System.out.println("Output stream: " + out.toString());      
            //能将输入流同时拷贝到两个输出流
            ByteArrayOutputStream out1 = new ByteArrayOutputStream();
            ByteArrayOutputStream out2 = new ByteArrayOutputStream();
            
            teeOut = new TeeOutputStream(out1, out2);
            teeIn = new TeeInputStream(in, teeOut, true);
            teeIn.read(new byte[INPUT.length()]);

            System.out.println("Output stream 1: " + out1.toString());
            System.out.println("Output stream 2: " + out2.toString());
            
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //此处不需要关闭teeOut,当关闭teeIn时,同时会关闭teeOut
            try { teeIn.close();
            tee.close();}
            catch (IOException e) { e.printStackTrace(); }
        }
    }

4、Filters,commons-io提供了多种过滤器,能够根据条件过滤指定目录下的文件,同时还支持过滤器组合,

示例如下

 private static final String PARENT_DIR =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio";

    public static void runExample() {
        System.out.println("File Filter example...");
        
        
        // NameFileFilter:获取指定目录下,符合给定文件列表的文件
        //例如获取此例,获取PARENT_DIR目录下commonios和commonio.txt文件
        File dir = FileUtils.getFile(PARENT_DIR);
        String[] acceptedNames = {"commonios", "commonio.txt"};
        for (String file: dir.list(new NameFileFilter(acceptedNames, IOCase.INSENSITIVE))) {
            System.out.println("File found, named: " + file);
        }
        
        
        //WildcardFileFilter:支持正则匹配,获取指定目录下,满足正则的文件
        for (String file: dir.list(new WildcardFileFilter("*common*"))) {
            System.out.println("Wildcard file found, named: " + file);
        }
        
        
        // PrefixFileFilter:获取以给定字符串为前缀的文件名
        for (String file: dir.list(new PrefixFileFilter("common"))) {
            System.out.println("Prefix file found, named: " + file);
        }
        
        
        // SuffixFileFilter::获取以给定字符串为后缀的文件名
        for (String file: dir.list(new SuffixFileFilter(".txt"))) {
            System.out.println("Suffix file found, named: " + file);
        }
        
        
        // OrFileFilter:支持传入多个过滤器,过滤器之间是或的关系
        for (String file: dir.list(new OrFileFilter(
                new WildcardFileFilter("*ample*"), new SuffixFileFilter(".txt")))) {
            System.out.println("Or file found, named: " + file);
        }
        
        //AndFileFilter:支持传入多个过滤器,过滤器之间是且的关系
        for (String file: dir.list(new AndFileFilter( 
                new WildcardFileFilter("*ample*"), 
                new NotFileFilter(new SuffixFileFilter(".txt"))))) { 
            System.out.println("And/Not file found, named: " + file);
        }
    }

5、Comparators,commons-io提供了多种文件比较工具类,能够根据文件名称、文件大小、修改时间等对目录下的文件进行排序,

简单示例如下

private static final String PARENT_DIR =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio";
    
    private static final String FILE_1 =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/commonio.txt";
    
    private static final String FILE_2 =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/test.xml";
    
    public static void runExample() {
        System.out.println("Comparator example...");
        
        //NameFileComparator:根据文件名称排序,IOCase表示是否大小写敏感
        
        File parentDir = FileUtils.getFile(PARENT_DIR);
        NameFileComparator comparator = new NameFileComparator(IOCase.SENSITIVE);
        File[] sortedFiles = comparator.sort(parentDir.listFiles());
        
        System.out.println("Sorted by name files in parent directory: ");
        for (File file: sortedFiles) {
            System.out.println("\t"+ file.getAbsolutePath());
        }
        
        
        // SizeFileComparator:根据文件大小排序,小文件在前,其构造器支持传一个boolean类型的参数,
        //true表示需要计算该目录下的目录大小
        //flase表示不需要计算该目录下的目录大小(0)
        
        SizeFileComparator sizeComparator = new SizeFileComparator(true);
        File[] sizeFiles = sizeComparator.sort(parentDir.listFiles());
        
        System.out.println("Sorted by size files in parent directory: ");
        for (File file: sizeFiles) {
            System.out.println("\t"+ file.getName() + " with size (kb): " + file.length());
        }
        
        
        // LastModifiedFileComparator:根据修改时间排序,最新修改排前
        LastModifiedFileComparator lastModified = new LastModifiedFileComparator();
        File[] lastModifiedFiles = lastModified.sort(parentDir.listFiles());
        
        System.out.println("Sorted by last modified files in parent directory: ");
        for (File file: lastModifiedFiles) {
            Date modified = new Date(file.lastModified());
            System.out.println("\t"+ file.getName() + " last modified on: " + modified);
        }
    }

6、File Monitor,commons-io还提供了对目录的监控类,可以对指定目录进行监控,如果目录下文件发生变化(修改,增加,删除等),其监控会向监听器发送相应的事件。

示例如下

private static final String EXAMPLE_PATH =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/commonio.txt";
    
    private static final String PARENT_DIR =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio";
    
    private static final String NEW_DIR =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/newDir";
    
    private static final String NEW_FILE =
            "/Users/fly/work/GitHub/algorithm/src/main/java/com/fly/practice/apachecommonsio/newFile.txt";

    public static void runExample() {
        System.out.println("File Monitor example...");
        
        
        // FileEntry
        
        // We can monitor changes and get information about files
        // using the methods of this class.
        FileEntry entry = new FileEntry(FileUtils.getFile(EXAMPLE_PATH));
        
        System.out.println("File monitored: " + entry.getFile());
        System.out.println("File name: " + entry.getName());
        System.out.println("Is the file a directory?: " + entry.isDirectory());
        
        
        // 文件(目录)监控
        
        // 给指定目录创建观察者,并添加监听器,对事件作出响应
        File parentDir = FileUtils.getFile(PARENT_DIR);
        
        FileAlterationObserver observer = new FileAlterationObserver(parentDir);
        observer.addListener(new FileAlterationListenerAdaptor() {
            
                @Override
                public void onFileCreate(File file) {
                    System.out.println("File created: " + file.getName());
                }
                
                @Override
                public void onFileDelete(File file) {
                    System.out.println("File deleted: " + file.getName());
                }
                
                @Override
                public void onDirectoryCreate(File dir) {
                    System.out.println("Directory created: " + dir.getName());
                }
                
                @Override
                public void onDirectoryDelete(File dir) {
                    System.out.println("Directory deleted: " + dir.getName());
                }
        });
        
        // 创建一个每隔500毫秒就做一次检查的监控
        FileAlterationMonitor monitor = new FileAlterationMonitor(500, observer);
        try {
            monitor.start();
            //启动监控后,对监控目录做一些文件操作,触发监听器
            File newDir = new File(NEW_DIR);
            File newFile = new File(NEW_FILE);
            
            newDir.mkdirs();
            newFile.createNewFile();
                
            Thread.sleep(1000);
            
            FileDeleteStrategy.NORMAL.delete(newDir);
            FileDeleteStrategy.NORMAL.delete(newFile);
            
            Thread.sleep(1000);
            
            monitor.stop();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
以上只是对commons-io的一个简单介绍,从中可以看出该工具包提供了强大的IO操作,更多功能还需实际项目中不断探索


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。