using XGame.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
namespace XGame.Editor.Asset
{
public static class FileUtil
{
/////
///// 收集指定路径下的指定后缀的文件
/////
/////
/////
/////
/////
//public static List CollectFiles(string rootPath, string[] patterns, bool isFindSelected)
//{
// List allFiles = new List();
// if (!Directory.Exists(rootPath))
// return allFiles;
// foreach (var pattern in patterns)
// {
// var files = Directory.GetFiles(rootPath, pattern, SearchOption.AllDirectories);
// foreach (var file in files)
// allFiles.Add(file.Replace("\\", "/"));
// }
// // 只对选择物体打包
// if (isFindSelected)
// {
// // 返回一个交集 就是判断当前选择是否满足条件
// return allFiles.Intersect(Selection.objects.Select(AssetDatabase.GetAssetPath)).ToList();
// }
// else
// {
// return allFiles;
// }
//}
///
/// 贴图文件后缀
///
public static readonly string[] texturePatterns = { ".png", ".jpg", ".tga", ".psd" };
private static readonly string textureExts = ".png.jpg.tga.psd";
///
/// 图集配置文件后缀
///
public static readonly string spriteatlasPattern = ".spriteatlas";
///
/// 文件是否是Texture
///
///
///
public static bool IsTextureFile(string filePath)
{
var ext = Path.GetExtension(filePath);
return string.IsNullOrEmpty(ext) == false && textureExts.Contains(ext, StringComparison.OrdinalIgnoreCase);
}
///
/// 是否是SpriteAtlas文件
///
///
///
public static bool IsSpriteAtlas(string filePath)
{
return filePath.EndsWith(spriteatlasPattern, StringComparison.OrdinalIgnoreCase);
}
///
/// 查找指定文件夹下的指定类型的文件
///
///
/// 文件后缀名
///
///
public static string[] FindFiles(string path, string[] patterns, SearchOption option = SearchOption.AllDirectories)
{
if (!Directory.Exists(path) || patterns == null)
{
return new string[0];
}
var files = Directory.GetFiles(path, "*.*", option).Where(file =>
{
foreach (var pattern in patterns)
{
if (file.EndsWith(pattern))
{
return true;
}
}
return false;
}).ToArray();
for (var i = 0; i < files.Length; i++)
{
files[i] = files[i].Replace("\\", "/");
}
return files;
}
///
/// 查找指定文件夹下的指定类型的文件
///
///
/// 必须使用"*."开头
///
///
public static string[] FindFiles(string path, string pattern, SearchOption option = SearchOption.AllDirectories)
{
if (!Directory.Exists(path) || string.IsNullOrEmpty(pattern))
{ //文件夹不存在或后缀名为空
return new string[0];
}
//必须使用"*."开头
if (pattern.StartsWith("."))
{
pattern = $"*{pattern}";
}
var files = Directory.GetFiles(path, pattern, option);
for (var i = 0; i < files.Length; i++)
{
files[i] = files[i].Replace("\\", "/");
}
return files;
}
///
/// 查找指定路径下的所有文件
///
///
///
public static string[] FindFiles(string path)
{
List lst = new List();
FindFiles(path, (files) =>
{
lst.AddRange(files);
});
return lst.ToArray();
}
///
/// 查找指定路径下的所有文件,按照所在文件夹批次返回结果
/// path为全路径,则返回的也是全路径
/// path为AssetPath,则返回的也是AssetPath
///
///
///
public static void FindFiles(string path, System.Action action)
{
var lst = new List();
var files = Directory.GetFiles(path).Where((file) => !IsFileIgnore(file)).ToArray();
if (files.Length > 0 && action != null)
{
for (var i = 0; i < files.Length; i++)
{
files[i] = files[i].Replace("\\", "/");
}
action.Invoke(files);
}
var dirs = Directory.GetDirectories(path);
foreach (var dir in dirs)
{
FindFiles(dir, action);
}
}
///
/// 忽略的文件格式
///
//static readonly string[] ignoreFiles = { ".meta", ".gitkeep", ".spriteatlas", ".DS_Store", ".cs", ".pdb" };
static readonly string ignoreFiles = "*.meta*.gitkeep*.spriteatlas*.DS_Store*.cs*.pdb";
public static bool IsFileIgnore(string path)
{
//if (!File.Exists(path))
//{
// return true;
//}
var ext = Path.GetExtension(path);
return string.IsNullOrEmpty(ext) == false && ignoreFiles.Contains(ext, StringComparison.OrdinalIgnoreCase);
}
///
/// 获取文件所在文件夹的名字
///
///
///
///
public static string GetDirectoryName(string path, bool fullName)
{
path = Path.GetDirectoryName(path)?.Replace("\\", "/");
if (!fullName)
{
int idx = path?.LastIndexOf("/", StringComparison.Ordinal) ?? -1;
if (idx != -1)
{
path = path?.Substring(idx + 1);
}
}
return path;
}
///
/// 全路径转相对路径
/// (Assets/...)
///
///
///
public static string ToRelativePath(string fullPath)
{
int index = fullPath.IndexOf(PathDefine.AssetsRelative, StringComparison.Ordinal);
if (index == 0)
{
return fullPath;
}
else if (index < 0)
{ //没有 "Assets/" 或者在开头
index = fullPath.IndexOf(PathDefine.PackageRelative, StringComparison.Ordinal); //Packages里的资源以Packages/开头,全名为"Packages/{包名}/..."
if (index == 0)
{//Packages下资源的相对路径
return fullPath;
}
else if (index < 0)
{
var packageRoot = PathDefine.PackageReality;
index = fullPath.IndexOf(packageRoot, StringComparison.Ordinal);
if (index >= 0)
{
//Packages下资源的全路径
var tempPath = fullPath.Substring(index + packageRoot.Length);
var index_0 = tempPath.IndexOf('@');
var index_1 = tempPath.IndexOf('/');
if (index_1 - index_0 > 0 && index_0 >= 0)
{//裁剪版本信息
var version = tempPath.Substring(index_0, index_1 - index_0);
tempPath = $"{PathDefine.PackageRelative}{tempPath.Replace(version, "")}";
}
return tempPath;
}
return fullPath;
}
}
return fullPath.Substring(index);
}
///
/// 判断字符串是否是数字
///
///
///
///
public static bool IsNumberic(string message, out int result)
{
System.Text.RegularExpressions.Regex rex =
new System.Text.RegularExpressions.Regex(@"^\d+$");
result = -1;
if (rex.IsMatch(message))
{
result = int.Parse(message);
return true;
}
else
return false;
}
///
/// 检测指定路径是否是包含平台信息
/// result 返回1表是当前平台,返回-1表示包含平台信息但不是当前平台,返回0表示没有包含平台信息
///
///
///
///
public static int VerifyPlatformPath(string path, string[] platformNames = null)
{
if (platformNames == null)
{
platformNames = Enum.GetNames(typeof(PlatformType));
}
var current = PlatformUtil.ActivePlatform.ToString();
var projectPath = Environment.CurrentDirectory.Replace("\\", "/");
var startIndex = path.StartsWith(projectPath) ? projectPath.Length : 0;
foreach (var name in platformNames)
{
var platformIndex = path.IndexOf(name, startIndex);
if (platformIndex >= 0)
{
if (name.Equals(current))
{
return 1;
}
return -1;
}
}
return 0;
}
///
/// 可加载资源路径
///
///
///
public static string[] GetProductAssetsRoots(bool includeResources = false)
{
ICollection roots = new HashSet();
if (Directory.Exists(PathDefine.ResAddressableRelative))
{
roots.Add(PathDefine.ResAddressableRelative);
}
if (includeResources && Directory.Exists(PathDefine.ResourcesRelative))
{
roots.Add(PathDefine.ResourcesRelative);
}
GetDirectories(PathDefine.I18nAssetsRelative, PathDefine.ResAddressableName, SearchOption.AllDirectories, ref roots);
return roots.ToArray();
}
public static string[] GetI18nAssetsRoots()
{
ICollection directories = new HashSet();
GetDirectories(PathDefine.I18nAssetsRelative, PathDefine.ResAddressableName, SearchOption.AllDirectories, ref directories);
return directories.ToArray();
}
///
/// 获取图集文件夹
/// 文件夹名字:Atlas
///
///
public static string[] GetAtlasRoots()
{
const string atlasDir = "Atlas";
ICollection directories = new HashSet();
GetDirectories(PathDefine.ResAddressableRelative, atlasDir, SearchOption.AllDirectories, ref directories);
GetDirectories(PathDefine.ResStaticRelative, atlasDir, SearchOption.AllDirectories, ref directories);
GetDirectories(PathDefine.I18nAssetsRelative, atlasDir, SearchOption.AllDirectories, ref directories);
return directories.ToArray();
}
private static void GetDirectories(string path, string searchPattern, SearchOption searchOption, ref ICollection directories)
{
if (Directory.Exists(path))
{
var result = Directory.GetDirectories(path, searchPattern, searchOption);
foreach (var directory in result)
{
directories.Add(directory.Replace("\\", "/"));
}
}
}
public static bool HasChinese(string str)
{
return System.Text.RegularExpressions.Regex.IsMatch(str, @"[\u4e00-\u9fa5]");
}
//[UnityEditor.MenuItem("Tools/Test/GenManifestBundleId")]
//public static void GenManifestBundleId()
//{
// var str = $"ProductAssetManifest.asset_AssetBundleManifest.asset_AssetReferenceManifest.asset";
// var bundleId = Crc32.GetCrc32(str);
// Debug.Log($"GenManifestBundleId:{bundleId}");
//}
}
}