通过递归与访问者模式过滤文件

在阅读Fresco源码时看到一个遍历文件的小模块,职责清晰、设计精妙、关键有着很高的拓展性,在研究之后果断代码收藏。

思路:利用递归遍历整个目录,如果是文件,访问者执行访问。

文件树

public class FileTree {

    /**
     * 遍历目录的文件树,并接收一个访问者访问每一个文件。
     * @param directory 要遍历的文件
     * @param visitor 访问者
     */
    public static void walkFileTree(File directory, FileTreeVisitor visitor) {
        visitor.preVisitDirectory(directory);
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file: files) {
                if (file.isDirectory()) {
                    walkFileTree(file, visitor);
                } else {
                    visitor.visitFile(file);
                }
            }
        }
        visitor.postVisitDirectory(directory);
    }

    /**
     * 删除目录中的所有文件和子目录
     * @param directory 要删除的目录
     */
    public static boolean deleteContents(File directory) {
        File[] files = directory.listFiles();
        boolean success = true;
        if (files != null) {
            for (File file : files) {
                success &= deleteRecursively(file);
            }
        }
        return success;
    }

    /**
     * 删除该文件,如果它是一个目录,则删除其中任何内容
     * @param file 要删除的文件
     */
    public static boolean deleteRecursively(File file) {
        if (file.isDirectory()) {
            deleteContents(file);
        }
        return file.delete();
    }
}
访问者
public interface FileTreeVisitor {

    /**
     * 遍历目录前执行
     * @param directory
     */
    void preVisitDirectory(File directory);

    /**
     * 访问文件
     * @param file
     */
    void visitFile(File file);

    /**
     * 遍历目录后执行
     * @param directory
     */
    void postVisitDirectory(File directory);

}
测试过滤图片文件(格式为png,jpg)
public class FileImageVisitor implements FileTreeVisitor {

    public static final String PNG = "png"; //格式为png的图片
    public static final String JPG = "jpg"; //格式为jpg的图片

    private boolean first;

    private File rootFile; //过滤目录
    private List<String> images; //过滤结果
    private FilterCallBack callBack; //过滤回调
    
    public FileImageVisitor() {
        images = new ArrayList<>();
    }

    @Override
    public void preVisitDirectory(File directory) {
        if (!first) {
            rootFile = directory;
            first = true;
            L.d("扫描开始");
        }
    }

    @Override
    public void visitFile(File file) {
        String fileName = file.getAbsolutePath();
        String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);
        if (prefix.equals(PNG) || prefix.equals(JPG)) {
            images.add(file.getAbsolutePath());
        }
    }

    @Override
    public void postVisitDirectory(File directory) {
        if (first && rootFile != null) {
            if (rootFile == directory) {
                L.d("文件扫描结束");
               if (callBack != null) {
                    callBack.onFilterFinish(images);
                }
            }
        }
    }

    /**
     * 过滤回调接口
     */
    public interface FilterCallBack {
        //过滤结束
        void onFilterFinish(List<String> image);
    }

    public void setFilterCallBack(FilterCallBack callBack) {
        this.callBack = callBack;
    }
}
测试
        FileImageVisitor imageVisitor = new FileImageVisitor();
        imageVisitor.setFilterCallBack(new FileImageVisitor.FilterCallBack() {
            @Override
            public void onFilterFinish(List<String> images) {
                L.d("扫描图片个数:" + images.size());
                for (String url : images) {
                    L.d("图片路径:" + url);
                }
            }
        });
        FileTree.walkFileTree(Environment.getExternalStorageDirectory(), imageVisitor);

结果
文件扫描开始
文件扫描结束
扫描图片个数:611
图片路径:/system/etc/letvTheme_3rd_default/icons_1080p/air.fyzb3.png
图片路径:/system/etc/letvTheme_3rd_default/icons_1080p/android.png
图片路径:/system/etc/letvTheme_3rd_default/icons_1080p/bubei.tingshu.png
图片路径:/system/etc/letvTheme_3rd_default/icons_1080p/cc.fotoplace.app.png
图片路径:/system/etc/letvTheme_3rd_default/icons_1080p/cld.navi.mainframe.png
图片路径:/system/etc/letvTheme_3rd_default/icons_1080p/cmb.pb.png
图片路径:/system/etc/letvTheme_3rd_default/icons_1080p/cmccwm.mobilemu
.
.
.省略
提示:放入GridView显示,加载的图片会比手机图库的多,小心哦。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值