在阅读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显示,加载的图片会比手机图库的多,小心哦。