Chapter 18 - Exercise 4

(2) Use Directory.walk( ) to sum the sizes of all files in a directory tree whose names match a particular regular expression.


description: > (1) Modify ProcessFiles.java so that it matches a regular expression rather than a fixed extension. — description: > (5) Use ProcessFiles to find all the Java source-code files in a particular directory subtree that have been modified after a particular date. —

Directory.java

简化练习4中的Directory类。



package com.ciaoshen.thinkinjava.chapter18;
import java.util.*;
import java.io.*;
import java.util.regex.*;

public class Directory{
    private List<File> files=new ArrayList<File>();
    private List<File> dirs=new ArrayList<File>();
    private int size=0;
    private int lines=0;

    public Directory(){this(".");}
    public Directory(String dir){this(new File(dir));}
    public Directory(File dir){this(dir,".*");}
    public Directory(String dir, String regex){this(new File(dir),regex);}
    public Directory(File dir,String regex){
        recurseDirs(dir,new FilenameFilter(){
            private Pattern p=Pattern.compile(regex);
            public boolean accept(File dir,String name){
                return p.matcher(name).matches();
            }
        });
        statistic();
    }
    public Directory(File dir,FilenameFilter filter){
        recurseDirs(dir,filter);
        statistic();
    }

    //递归收集文件
    public void recurseDirs(File dir, FilenameFilter filter){
        File[] children=dir.listFiles();
        if(children==null || children.length==0){return;}
        for(File f:children){
            if(f.isDirectory()){
                dirs.add(f);
                recurseDirs(f,filter);
            }else{
                if(filter.accept(dir,f.getName())){
                    files.add(f);
                }
            }
        }
    }

    public void statistic(){
        if(files!=null && files.size()>0){
            size=files.size();
            int num=0;
            for(File file:files){
                try{
                    BufferedReader bf=new BufferedReader(new FileReader(file));
                    while(bf.readLine()!=null){
                        num++;
                    }
                }catch(Exception e){
                    System.out.println(file.getName()+" can not open!");
                }
            }
            lines=num;
        }
    }

    public List<File> getFile(){return files;}
    public List<File> getDir(){return dirs;}
    public void showStatistic(){System.out.println("File number:    "+size+"\n"+"Total Lines:   "+lines+"\n");}
}


Exercise4.java



package com.ciaoshen.thinkinjava.chapter18;
import java.util.*;
import java.io.*;
import java.util.regex.*;

public class Exercise4{
    public static void main(String[] args){
        Directory d=new Directory("/Users/Wei/java/com/ciaoshen/thinkinjava/chapter17/testframework/",".*Gen.*");
        d.showStatistic();
        List<File> files=d.getFile();
        List<File> dirs=d.getDir();
        if(files!=null  && !(files.size()==0)){
            System.out.println(files);
        }
        if(dirs!=null  && !(dirs.size()==0)){
            System.out.println(dirs);
        }
    }
}


ProcessFiles.java

ProcessFiles配合Directory使用。由Directory递归读取文件,然后由ProcessFiles里的Strategy模块处理。



package com.ciaoshen.thinkinjava.chapter18;
import java.util.*;
import java.io.*;
import java.util.regex.*;

public class ProcessFiles {
    public interface Strategy {
        void process(File file);
    }
    private Strategy strategy;
    private String ext;
    public ProcessFiles(Strategy strategy, String ext) {
        this.strategy = strategy;
        this.ext = ext;
    }
    public void start(String[] args){
        try{
            if(args.length==0){
                processDirectoryTree(new File("."));
            }else{
                for(String arg:args){
                    processDirectoryTree(new File(arg));
                }
            }
        }catch(IOException e) {
            throw new RuntimeException(e);
        }
    }
    public void processDirectoryTree(File root) throws IOException {
        for(File file : new Directory(root.getAbsolutePath(), ".*\\." + ext).getFile()){
            strategy.process(file.getCanonicalFile());
        }
    }
    // Demonstration of how to use it:
    public static void main(String[] args) {
        new ProcessFiles(new ProcessFiles.Strategy() {
            public void process(File file) {
                System.out.println(file);
            }
        }, "java").start(args);
    }
}


Exercise5.java



package com.ciaoshen.thinkinjava.chapter18;
import java.util.*;
import java.io.*;
import java.util.regex.*;

public class Exercise5{
    public static void main(String[] args){
        new ProcessFiles(new ProcessFiles.Strategy() {
            public void process(File file) {
                System.out.println(file);
            }
        }, "ja.*").start(args);
    }
    }
}


Exercise6.java

用Directory和ProcessFile,对File做时间过滤。加了两个“时间-日期”转换方法。



package com.ciaoshen.thinkinjava.chapter18;
import java.util.*;
import java.io.*;
import java.util.regex.*;
import java.text.*;

public class Exercise6{

    public static void filterByModifyDate(String[] args, String date){
        new ProcessFiles(new ProcessFiles.Strategy() {
            private long time=getNanoTime(date);
            public void process(File file) {
                if(file.lastModified()>time){
                    System.out.println(file+"   >>>Last Modified: "+getFormatDate(file.lastModified()));
                }
            }
        }, "java").start(args);
    }

    public static long getNanoTime(String date){
        try{
            DateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd");
            Date myDate = dateFormat1.parse(date);
            return myDate.getTime();
        }catch(ParseException pe){
            System.out.println("Error when parsing Date!");
        }
        return 0l;
    }

    public static String getFormatDate(long millitime){
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(millitime).toString();
    }

    public static void main(String[] args){
        filterByModifyDate(args,"2016-09-29");
    }
}



Need Java Developers? Hire Me »

I know Java. Talk is cheap, watch my code.

I live in CANADA now.