All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.utils.common.assist.search.FileDepthFirstSearchUtils Maven / Gradle / Ivy

package dev.utils.common.assist.search;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import dev.utils.JCLogUtils;

/**
 * detail: 文件深度优先搜索算法 ( 递归搜索某个目录下的全部文件 )
 * @author Ttt
 */
public final class FileDepthFirstSearchUtils {

    // 日志 TAG
    private static final String TAG = FileDepthFirstSearchUtils.class.getSimpleName();

    /**
     * 构造函数
     */
    public FileDepthFirstSearchUtils() {
    }

    /**
     * 构造函数
     * @param searchHandler 搜索处理接口
     */
    public FileDepthFirstSearchUtils(final SearchHandler searchHandler) {
        this.mSearchHandler = searchHandler;
    }

    /**
     * detail: 文件信息 Item
     * @author Ttt
     */
    public static final class FileItem {

        public FileItem(final File file) {
            this.file = file;
        }

        // 文件
        public File file;

        // 子文件夹目录
        public List listChilds = null;
    }

    /**
     * detail: 搜索处理接口
     * @author Ttt
     */
    public interface SearchHandler {

        /**
         * 判断是否处理该文件
         * @param file 文件
         * @return {@code true} 处理该文件, {@code false} 跳过该文件不处理
         */
        boolean isHandlerFile(File file);

        /**
         * 是否添加到集合
         * @param file 文件
         * @return {@code true} 添加, {@code false} 不添加
         */
        boolean isAddToList(File file);

        /**
         * 搜索结束监听
         * @param lists     根目录的子文件目录集合
         * @param startTime 开始扫描时间
         * @param endTime   扫描结束时间
         */
        void onEndListener(
                List lists,
                long startTime,
                long endTime
        );
    }

    // 搜索处理接口
    private SearchHandler mSearchHandler;

    // 内部实现接口
    private final SearchHandler mInnerHandler = new SearchHandler() {
        @Override
        public boolean isHandlerFile(File file) {
            if (mSearchHandler != null) {
                return mSearchHandler.isHandlerFile(file);
            }
            return true;
        }

        @Override
        public boolean isAddToList(File file) {
            if (mSearchHandler != null) {
                return mSearchHandler.isAddToList(file);
            }
            return true;
        }

        @Override
        public void onEndListener(
                List lists,
                long startTime,
                long endTime
        ) {
            // 表示非搜索中
            mRunning = false;
            // 触发回调
            if (mSearchHandler != null) {
                mSearchHandler.onEndListener(lists, startTime, endTime);
            }
        }
    };

    /**
     * 设置搜索处理接口
     * @param searchHandler 搜索处理接口
     * @return {@link FileDepthFirstSearchUtils}
     */
    public FileDepthFirstSearchUtils setSearchHandler(final SearchHandler searchHandler) {
        this.mSearchHandler = searchHandler;
        return this;
    }

    /**
     * 是否搜索中
     * @return {@code true} 搜索 / 运行中, {@code false} 非搜索 / 运行中
     */
    public boolean isRunning() {
        return mRunning;
    }

    /**
     * 停止搜索
     */
    public void stop() {
        mStop = true;
    }

    /**
     * 是否停止搜索
     * @return {@code true} 已停止搜索, {@code false} 搜索中
     */
    public boolean isStop() {
        return mStop;
    }

    /**
     * 获取开始搜索时间 ( 毫秒 )
     * @return 开始搜索时间 ( 毫秒 )
     */
    public long getStartTime() {
        return mStartTime;
    }

    /**
     * 获取结束搜索时间 ( 毫秒 )
     * @return 结束搜索时间 ( 毫秒 )
     */
    public long getEndTime() {
        return mEndTime;
    }

    // =

    // 判断是否运行中
    private boolean mRunning   = false;
    // 是否停止搜索
    private boolean mStop      = false;
    // 开始搜索时间
    private long    mStartTime = 0L;
    // 结束搜索时间
    private long    mEndTime   = 0L;

    /**
     * 搜索目录
     * @param path       根目录路径
     * @param isRelation 是否关联到 Child List
     */
    public synchronized void query(
            final String path,
            final boolean isRelation
    ) {
        if (mRunning) {
            return;
        } else if (path == null || path.trim().length() == 0) {
            // 触发结束回调
            mInnerHandler.onEndListener(null, -1, -1);
            return;
        }
        // 表示运行中
        mRunning = true;
        mStop    = false;
        // 设置开始搜索时间
        mStartTime = System.currentTimeMillis();
        try {
            // 获取根目录 File
            final File file = new File(path);
            // 判断是否文件
            if (file.isFile()) {
                List lists = new ArrayList<>();
                lists.add(new FileItem(file));
                // 触发结束回调
                mEndTime = System.currentTimeMillis();
                mInnerHandler.onEndListener(lists, mStartTime, mEndTime);
                return;
            }
            // 获取文件夹全部子文件
            String[] fileArrays = file.list();
            // 获取文件总数
            if (fileArrays != null && fileArrays.length != 0) {
                new Thread(() -> {
                    List lists = new ArrayList<>();
                    // 查询文件
                    queryFile(file, lists, isRelation);
                    // 触发结束回调
                    mEndTime = System.currentTimeMillis();
                    mInnerHandler.onEndListener(lists, mStartTime, mEndTime);
                }).start();
            } else {
                // 触发结束回调
                mEndTime = System.currentTimeMillis();
                mInnerHandler.onEndListener(null, mStartTime, mEndTime);
            }
        } catch (Exception e) {
            JCLogUtils.eTag(TAG, e, "query");
            // 触发结束回调
            mEndTime = System.currentTimeMillis();
            mInnerHandler.onEndListener(null, mStartTime, mEndTime);
        }
    }

    /**
     * 搜索文件
     * @param file       文件
     * @param lists      保存数据源
     * @param isRelation 是否关联到 Child List
     */
    private void queryFile(
            final File file,
            final List lists,
            final boolean isRelation
    ) {
        try {
            if (mStop) {
                return;
            }
            if (file != null && file.exists()) {
                // 判断是否处理
                if (mInnerHandler.isHandlerFile(file)) {
                    // 如果属于文件夹
                    if (file.isDirectory()) {
                        // 获取文件夹全部子文件
                        File[] files = file.listFiles();
                        if (files == null) {
                            return;
                        }
                        for (File queryFile : files) {
                            if (isRelation) {
                                if (queryFile.isDirectory()) {
                                    List childs = new ArrayList<>();
                                    // 查找文件
                                    queryFile(queryFile, childs, isRelation);
                                    // 保存数据
                                    FileItem fileItem = new FileItem(queryFile);
                                    fileItem.listChilds = childs;
                                    lists.add(fileItem);
                                } else {
                                    // 属于文件
                                    if (mInnerHandler.isAddToList(queryFile)) {
                                        // 属于文件则直接保存
                                        lists.add(new FileItem(queryFile));
                                    }
                                }
                            } else {
                                // 查找文件
                                queryFile(queryFile, lists, isRelation);
                            }
                        }
                    } else { // 属于文件
                        if (mInnerHandler.isAddToList(file)) {
                            // 属于文件则直接保存
                            lists.add(new FileItem(file));
                        }
                    }
                }
            }
        } catch (Exception e) {
            JCLogUtils.eTag(TAG, e, "queryFile");
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy