【游戏面包屑】文件路径遍历寻找目标文件

功能:指定目标文件绝对路径,寻找该路径下目标文件

以下是C#版本代码

    /// <summary>
    /// 遍历目标路径下所有文件寻找目标文件
    /// 找到文件后设置curPath为目标文件的Resources下的相对路径
    /// </summary>
    /// <param name="dirs">遍历的绝对路径</param>
    /// <param name="name">目标文件名(包含后缀)</param>
    private void director(string dirs,string name) {
        //绑定到指定的文件夹目录
        DirectoryInfo dir = new DirectoryInfo(dirs);
        //检索表示当前目录的文件和子目录
        FileSystemInfo[] fsinfos = dir.GetFileSystemInfos();
        //遍历检索的文件和子目录
        foreach (FileSystemInfo fsinfo in fsinfos) {
            //判断是否为空文件夹  
            if (fsinfo is DirectoryInfo) {
                //如果是文件夹,则递归调用
                director(fsinfo.FullName, name);
            }
            //判断文件名字是否符合目标
            else if(fsinfo.Name == name)
            {
                Debug.Log(fsinfo.FullName);
                //分割绝对路径FullName,寻找Resource,然后拼接接下来的字符串作为结果
                //绝对路径是使用'\'划分,使用转义字符
                string[] gets = fsinfo.FullName.Split('\\');
                //判定是否找到目标点
                bool isFind = false;
                for (int i = 0; i < gets.Length; i++) {
                    if (isFind) {
                        //拼接
                        if (name.CompareTo(gets[i])==0) {
                            //如果拼接时找到目标点,则去除其后缀
                            string[] end = gets[i].Split('.');
                            curPath += end[0];
                        }
                        else {
                            //如果拼接时不是目标点,则加个后缀'/'(文件夹没有后缀,不需要分割截取)
                            curPath += gets[i] + "/";
                        }
                    }
                    //找到拼接起始点(basic_resources = "Resources")
                    if (gets[i].CompareTo(basic_resources) == 0) {
                        //在此进行字符串拼接
                        isFind = true;
                    }
                }//for_end
            }
        }//foreach_end
        return;
    }

    /// <summary>
    /// UI窗口读取
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public GameObject Load_UI(string name) {
        GameObject prefab = null;
        //basic_ui = "ui/";
        string path = basic_ui + "Win_" + name;
        //应该改为在basic_ui文件夹下寻找是否符合name的文件
        /*测试*/
        //初始化curPath
        curPath = "";
        director(Application.dataPath+"/Resources/"+ basic_ui, "Win_" + name+".prefab");
        Debug.Log("结果路径:"+ curPath);
        prefab = Resources.Load(curPath) as GameObject;
        Debug.Log("寻找预设体:"+prefab);
        //prefab = Resources.Load(path) as GameObject;
        if (prefab == null) {
            Debug.LogError("Failed UIPrb_Local from " + path);
        }
        return prefab;
    }

结果:

【游戏面包屑】文件路径遍历寻找目标文件

请求3个UIPanel,并成功寻找到了,设置其节点为UIRoot2D.NormalPanel下。其中一个Panel存放在UI/Prefab/New Folder,也成功访问到了。


不足:

      如果目标路径下有其他相同的目标文件,只会更新到最后一个目标文件。正常情况下,Panel中只会有一个目标文件,可以在director进行判定以及异常信息,当有人为意外误操作时可以及时移除多余文件。或者手动进行文件搜索进行重复排查。


以下是新的优化的版本。添加了剪枝(优化性能)与重置数据。并针对上述的不足在备注里给了一种可能的解决方案。

   private string curPath = "";

    /// <summary>
    /// 遍历目标路径下所有文件寻找目标文件,当找到第一个符合条件的目标后结束遍历
    /// 找到文件后设置curPath为目标文件的Resources下的相对路径
    /// </summary>
    /// <param name="dirs">遍历的绝对路径</param>
    /// <param name="name">目标文件名(包含后缀)</param>
    /// <param name="isFirst">若为true,则重置curPath</param>
    private void director(string dirs,string name,bool isFirst = false) {
        //如果是true,则重置curPath值
        if (isFirst) {
            curPath = "";
        }
        //若不为空,则说明未重置curPath为空或已找到路径。默认情况下为已找到路径-结束整个遍历搜索
        if (!String.IsNullOrEmpty(curPath)) {
            return;
        }
        //绑定到指定的文件夹目录
        DirectoryInfo dir = new DirectoryInfo(dirs);
        //检索表示当前目录的文件和子目录
        FileSystemInfo[] fsinfos = dir.GetFileSystemInfos();
        //遍历检索的文件和子目录
        foreach (FileSystemInfo fsinfo in fsinfos) {
            //判断是否为空文件夹  
            if (fsinfo is DirectoryInfo) {
                //如果是文件夹,则递归调用
                director(fsinfo.FullName, name);
            }
            //判断文件名字是否符合目标
            else if(fsinfo.Name == name)
            {
                /*  若需要反馈重复目标,则可能需要这一句。本方法功能是遇到第一个符合条件就结束寻找。所以该逻辑不会运行到(若想运行则移除该方法头部的剪枝语句)。
                 *  读者可根据实际情况进行选择
                //如果找到一个新的符合目标文件,判定curPath是否为空。若不为空,则说明是重复目标,提示错误
                if (!String.IsNullOrEmpty(curPath)) {
                    Debug.LogError("已找到路径:"+ curPath + "\n新发现重复路径:" + fsinfo.FullName);
                }
                */
                //分割绝对路径FullName,寻找Resource,然后拼接接下来的字符串作为结果
                //绝对路径是使用'\'划分,使用转义字符
                string[] gets = fsinfo.FullName.Split('\\');
                //判定是否找到目标点
                bool isFind = false;
                for (int i = 0; i < gets.Length; i++) {
                    if (isFind) {
                        //拼接
                        if (name.CompareTo(gets[i])==0) {
                            //如果拼接时找到目标点,则去除其后缀
                            string[] end = gets[i].Split('.');
                            curPath += end[0];
                        }
                        else {
                            //如果拼接时不是目标点,则加个后缀'/'(文件夹没有后缀,不需要分割截取)
                            curPath += gets[i] + "/";
                        }
                    }
                    //找到拼接起始点(basic_resources = "Resources")
                    if (gets[i].CompareTo(basic_resources) == 0) {
                        //在此进行字符串拼接
                        isFind = true;
                    }
                }//for_end
            }
        }//foreach_end
        return;
    }

    /// <summary>
    /// UI窗口读取
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public GameObject Load_UI(string name) {
        GameObject prefab = null;
        //旧版本
        //basic_ui = "ui/";
        //string path = basic_ui + "Win_" + name;
        //prefab = Resources.Load(path) as GameObject;
        //每次寻找前,重置curPath(设置第三个参数为true或手动重置)
        director(Application.dataPath+"/Resources/"+ basic_ui, "Win_" + name+".prefab",true);
        prefab = Resources.Load(curPath) as GameObject;
        if (prefab == null) {
            Debug.LogError("Failed UIPrb_Local from " + curPath);
        }
        return prefab;
    }

 

上一篇:[转载]在Windows下搭建Android开发环境


下一篇:SpringBoot 框架中yml文件自定义常量及使用