zoukankan      html  css  js  c++  java
  • 使用nio对磁盘下的文件进行过滤

      上篇博文讲到为了解决tomcat日志自动清理的问题,翻看了tomcat-juli这个jar包。在FileHandler类下有一个利用nio完成对磁盘下过期文件进行过滤的功能实现,正好这段时间正在学习nio框架,所以特意抽离源码做了一下测试。以下将提供测试代码(主要代码摘抄自tomcat-juli.jar源码),与君共勉。

    package nio;
    
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.DirectoryStream;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.regex.Pattern;
    
    public class FilesFilter {
        private static int maxDays = 0;
        private static String directory = "E:\Program Files\Apache Software Foundation\Tomcat 8.5.24\logs";
        private static String prefix = "localhost.";
        private static String suffix = ".log";
        private static Pattern pattern = null;
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            pattern = Pattern
                    .compile("^(" + Pattern.quote(prefix) + ")\d{4}-\d{1,2}-\d{1,2}(" + Pattern.quote(suffix) + ")$");
    
            try {
                DirectoryStream<Path> files = streamFilesForDelete();
                System.out.println("准备输出:");
                for (Path file : files) {
                    // Files.delete(file);
                    System.out.println(file.toRealPath());
                }
            } catch (IOException e) {
                System.out.println("Unable to delete log files older than [" + maxDays + "] days");
            }
    
        }
        /**
         * 查询过期文件
         * @return
         * @throws IOException
         */
        private static DirectoryStream<Path> streamFilesForDelete() throws IOException {
            final Date maxDaysOffset = getMaxDaysOffset();
            final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            return Files.newDirectoryStream(new File(directory).toPath(), new DirectoryStream.Filter<Path>() {
                public boolean accept(Path path) throws IOException {
                    boolean result = false;
                    String date = obtainDateFromPath(path);
                    if (date != null) {
                        try {
                            Date dateFromFile = formatter.parse(date);
                            result = dateFromFile.before(maxDaysOffset);
                        } catch (ParseException e) {
                            // no-op
                        }
                    }
                    return result;
                }
            });
        }
    
        private static String obtainDateFromPath(Path path) {
            Path fileName = path.getFileName();
            if (fileName == null) {
                return null;
            }
            String date = fileName.toString();
            if (pattern.matcher(date).matches()) {
                date = date.substring(prefix.length());
                return date.substring(0, date.length() - suffix.length());
            } else {
                return null;
            }
        }
    
        private static Date getMaxDaysOffset() {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MILLISECOND, 0);
            cal.add(Calendar.DATE, -maxDays);
            return cal.getTime();
        }
    }

      代码重点只有一个: java.nio.file.Files.newDirectoryStream(Path dir,DirectoryStream.Filter<? super Path> filter),nio的Files类下newDirectoryStream方法用于获取指定磁盘下的物理文件列表Stream,该方法第二个参数可接收一个用于过滤的功能函数。实现accept方法,针对自己的场景自定义过滤条件。个人理解这种方式,可以在一次磁盘扫描中,完成无效文件过滤与符合条件文件的获取操作。比起传统的io对文件逐个扫描的操作,可以减少磁盘读写开销,有助于软件性能提升。当然,没有做过试验,在我这里还不算是一个结论。有这方面性能验证的朋友,可以给我留言解惑,谢谢!

  • 相关阅读:
    [内核编程] 串口过滤
    大数问题(高精度运算)
    [内核编程] 实战调试,第一个内核程序
    [内核编程] Windebug双机调试环境搭建
    树状数组
    mysql常用语句
    解决maven工程无法创建src/main/java包名的方法
    java Date中方法toLocaleString过时的替代方案
    Eclipse 无法编译,提示“错误: 找不到或无法加载主类”
    Eclipse如何设置编译文件.class输出路径
  • 原文地址:https://www.cnblogs.com/MrSi/p/8303468.html
Copyright © 2011-2022 走看看