Convert FileSystem::GetUniqueName into an instance method

Related: #1581
This commit is contained in:
ds5678 2025-09-21 00:19:04 -07:00
parent 9793a943a6
commit d8a5557478
5 changed files with 29 additions and 29 deletions

View File

@ -14,7 +14,7 @@ public abstract class ExportCollectionBase
} }
string fullName = $"{name}.{ExportExtension}"; string fullName = $"{name}.{ExportExtension}";
string uniqueName = FileSystem.GetUniqueName(path, fullName, FileSystem.MaxFileNameLength); string uniqueName = fileSystem.GetUniqueName(path, fullName, FileSystem.MaxFileNameLength);
string filePath = fileSystem.Path.Join(path, uniqueName); string filePath = fileSystem.Path.Join(path, uniqueName);
ContentExtractor.Export(asset, filePath, fileSystem); ContentExtractor.Export(asset, filePath, fileSystem);
} }
@ -42,7 +42,7 @@ public abstract class ExportCollectionBase
protected static string GetUniqueFileName(string directoryPath, string fileName, FileSystem fileSystem) protected static string GetUniqueFileName(string directoryPath, string fileName, FileSystem fileSystem)
{ {
return FileSystem.GetUniqueName(directoryPath, fileName, FileSystem.MaxFileNameLength); return fileSystem.GetUniqueName(directoryPath, fileName, FileSystem.MaxFileNameLength);
} }
public abstract IContentExtractor ContentExtractor { get; } public abstract IContentExtractor ContentExtractor { get; }

View File

@ -61,7 +61,7 @@ public abstract class ExportCollection : IExportCollection
} }
string fullName = $"{name}.{GetExportExtension(asset)}"; string fullName = $"{name}.{GetExportExtension(asset)}";
string uniqueName = FileSystem.GetUniqueName(path, fullName, FileSystem.MaxFileNameLength - MetaExtension.Length); string uniqueName = fileSystem.GetUniqueName(path, fullName, FileSystem.MaxFileNameLength - MetaExtension.Length);
string filePath = fileSystem.Path.Join(path, uniqueName); string filePath = fileSystem.Path.Join(path, uniqueName);
AssetExporter.Export(container, asset, filePath, fileSystem); AssetExporter.Export(container, asset, filePath, fileSystem);
Meta meta = new Meta(GUID, importer); Meta meta = new Meta(GUID, importer);
@ -89,7 +89,7 @@ public abstract class ExportCollection : IExportCollection
protected static string GetUniqueFileName(string directoryPath, string fileName, FileSystem fileSystem) protected static string GetUniqueFileName(string directoryPath, string fileName, FileSystem fileSystem)
{ {
return FileSystem.GetUniqueName(directoryPath, fileName, FileSystem.MaxFileNameLength - MetaExtension.Length); return fileSystem.GetUniqueName(directoryPath, fileName, FileSystem.MaxFileNameLength - MetaExtension.Length);
} }
protected virtual string GetExportExtension(IUnityObjectBase asset) protected virtual string GetExportExtension(IUnityObjectBase asset)

View File

@ -9,12 +9,12 @@ public static class FileUtilsTests
{ {
// A length 3 cont cont cont // A length 3 cont cont cont
// 01000001 11100110 10010110 10000111 00001010 // 01000001 11100110 10010110 10000111 00001010
Assert.That(FileSystem.GetUniqueName("/dir", "A文.ext", 4), Is.EqualTo(".ext")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文.ext", 4), Is.EqualTo(".ext"));
Assert.That(FileSystem.GetUniqueName("/dir", "A文.ext", 5), Is.EqualTo("A.ext")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文.ext", 5), Is.EqualTo("A.ext"));
Assert.That(FileSystem.GetUniqueName("/dir", "A文.ext", 6), Is.EqualTo("A.ext")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文.ext", 6), Is.EqualTo("A.ext"));
Assert.That(FileSystem.GetUniqueName("/dir", "A文.ext", 7), Is.EqualTo("A.ext")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文.ext", 7), Is.EqualTo("A.ext"));
Assert.That(FileSystem.GetUniqueName("/dir", "A文.ext", 8), Is.EqualTo("A文.ext")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文.ext", 8), Is.EqualTo("A文.ext"));
Assert.That(FileSystem.GetUniqueName("/dir", "A文.ext", 9), Is.EqualTo("A文.ext")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文.ext", 9), Is.EqualTo("A文.ext"));
} }
} }
@ -23,11 +23,11 @@ public static class FileUtilsTests
{ {
using (Assert.EnterMultipleScope()) using (Assert.EnterMultipleScope())
{ {
Assert.That(FileSystem.GetUniqueName("/dir", "A文.ext", 7), Is.EqualTo("A.ext")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文.ext", 7), Is.EqualTo("A.ext"));
Assert.That(FileSystem.GetUniqueName("/dir", "A文.ext", 8), Is.EqualTo("A文.ext")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文.ext", 8), Is.EqualTo("A文.ext"));
Assert.That(FileSystem.GetUniqueName("/dir", "A文.exte", 8), Is.EqualTo("A.exte")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文.exte", 8), Is.EqualTo("A.exte"));
Assert.That(FileSystem.GetUniqueName("/dir", "A文.exte", 9), Is.EqualTo("A文.exte")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文.exte", 9), Is.EqualTo("A文.exte"));
} }
} }
@ -36,8 +36,8 @@ public static class FileUtilsTests
{ {
using (Assert.EnterMultipleScope()) using (Assert.EnterMultipleScope())
{ {
Assert.That(FileSystem.GetUniqueName("/dir", "A文", 3), Is.EqualTo("A")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文", 3), Is.EqualTo("A"));
Assert.That(FileSystem.GetUniqueName("/dir", "A文", 4), Is.EqualTo("A文")); Assert.That(new VirtualFileSystem().GetUniqueName("/dir", "A文", 4), Is.EqualTo("A文"));
} }
} }
} }

View File

@ -52,41 +52,41 @@ public partial class FileSystem
} }
} }
public static string GetUniqueName(string dirPath, string fileName, int maxNameLength) public string GetUniqueName(string dirPath, string fileName, int maxNameLength)
{ {
string? ext = null; string? ext = null;
string? name = null; string? name = null;
string validFileName = fileName; string validFileName = fileName;
if (Encoding.UTF8.GetByteCount(fileName) > maxNameLength) if (Encoding.UTF8.GetByteCount(fileName) > maxNameLength)
{ {
ext = System.IO.Path.GetExtension(validFileName); ext = Path.GetExtension(validFileName);
name = Utf8Truncation.TruncateToUTF8ByteLength(fileName, maxNameLength - Encoding.UTF8.GetByteCount(ext)); name = Utf8Truncation.TruncateToUTF8ByteLength(fileName, maxNameLength - Encoding.UTF8.GetByteCount(ext));
validFileName = name + ext; validFileName = name + ext;
} }
if (!System.IO.Directory.Exists(dirPath)) if (!Directory.Exists(dirPath))
{ {
return validFileName; return validFileName;
} }
name ??= System.IO.Path.GetFileNameWithoutExtension(validFileName); name ??= Path.GetFileNameWithoutExtension(validFileName);
if (!IsReservedName(name)) if (!IsReservedName(name))
{ {
if (!System.IO.File.Exists(System.IO.Path.Join(dirPath, validFileName))) if (!File.Exists(Path.Join(dirPath, validFileName)))
{ {
return validFileName; return validFileName;
} }
} }
ext ??= System.IO.Path.GetExtension(validFileName); ext ??= Path.GetExtension(validFileName);
string key = System.IO.Path.Join(dirPath, $"{name}{ext}"); string key = Path.Join(dirPath, $"{name}{ext}");
UniqueNamesByInitialPath.TryGetValue(key, out int initial); UniqueNamesByInitialPath.TryGetValue(key, out int initial);
for (int counter = initial; counter < int.MaxValue; counter++) for (int counter = initial; counter < int.MaxValue; counter++)
{ {
string proposedName = $"{name}_{counter}{ext}"; string proposedName = $"{name}_{counter}{ext}";
if (!System.IO.File.Exists(System.IO.Path.Join(dirPath, proposedName))) if (!File.Exists(Path.Join(dirPath, proposedName)))
{ {
UniqueNamesByInitialPath[key] = counter; UniqueNamesByInitialPath[key] = counter;
return proposedName; return proposedName;
@ -95,7 +95,7 @@ public partial class FileSystem
throw new Exception($"Can't generate unique name for file {fileName} in directory {dirPath}"); throw new Exception($"Can't generate unique name for file {fileName} in directory {dirPath}");
} }
private static readonly Dictionary<string, int> UniqueNamesByInitialPath = new(); private Dictionary<string, int> UniqueNamesByInitialPath { get; } = [];
public static string RemoveCloneSuffixes(string path) public static string RemoveCloneSuffixes(string path)
{ {
@ -138,7 +138,7 @@ public partial class FileSystem
} }
} }
private static readonly Regex FileNameRegex = CreateFileNameRegex(); private static Regex FileNameRegex { get; } = CreateFileNameRegex();
public static string FixInvalidPathCharacters(string path) public static string FixInvalidPathCharacters(string path)
{ {
@ -166,14 +166,14 @@ public partial class FileSystem
return new Regex($@"[{escapedChars},\[\]\x00-\x1F]", RegexOptions.Compiled); return new Regex($@"[{escapedChars},\[\]\x00-\x1F]", RegexOptions.Compiled);
} }
private static readonly Regex PathRegex = CreatePathRegex(); private static Regex PathRegex { get; } = CreatePathRegex();
public static bool IsReservedName(string name) public static bool IsReservedName(string name)
{ {
return OperatingSystem.IsWindows() && name.Length is 3 or 4 && ReservedNames.Contains(name); return OperatingSystem.IsWindows() && name.Length is 3 or 4 && ReservedNames.Contains(name);
} }
private static readonly HashSet<string> ReservedNames = new(StringComparer.OrdinalIgnoreCase) private static HashSet<string> ReservedNames { get; } = new(StringComparer.OrdinalIgnoreCase)
{ {
"aux", "con", "nul", "prn", "aux", "con", "nul", "prn",
"com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",

View File

@ -101,7 +101,7 @@ internal static class Program
? FileSystem.FixInvalidFileNameCharacters(originalName) ? FileSystem.FixInvalidFileNameCharacters(originalName)
: $"{texture.ClassName}_{ToValidString(texture.PathID)}"; : $"{texture.ClassName}_{ToValidString(texture.PathID)}";
Debug.Assert(name.Length > 0); Debug.Assert(name.Length > 0);
string uniqueName = FileSystem.GetUniqueName(collectionOutputPath, name, FileSystem.MaxFileNameLength - jsonExtension.Length); string uniqueName = LocalFileSystem.Instance.GetUniqueName(collectionOutputPath, name, FileSystem.MaxFileNameLength - jsonExtension.Length);
string dataFilePath = Path.Join(collectionOutputPath, uniqueName); string dataFilePath = Path.Join(collectionOutputPath, uniqueName);
string infoFilePath = dataFilePath + jsonExtension; string infoFilePath = dataFilePath + jsonExtension;
File.WriteAllBytes(dataFilePath, data); File.WriteAllBytes(dataFilePath, data);