From a748da19095df55e2e15aa54c0cad3fc34c69e78 Mon Sep 17 00:00:00 2001 From: sin365 <353374337@qq.com> Date: Wed, 10 Sep 2025 20:25:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84NS=20IO=E7=9A=84API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Assets/Plugins/AxiNSApi/AxiNSIO.cs | 1332 ++++++++++------- 1 file changed, 787 insertions(+), 545 deletions(-) diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs index 9ad3c4a9..a9211848 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs @@ -1,26 +1,27 @@ #if UNITY_SWITCH using nn.fs; +using System.Text.RegularExpressions; #endif using System.Collections.Generic; -using System.Text.RegularExpressions; +using System; public class AxiNSIO { - string save_name => AxiNS.instance.mount.SaveMountName; - public string save_path => $"{save_name}:/"; + string save_name => AxiNS.instance.mount.SaveMountName; + public string save_path => $"{save_name}:/"; #if UNITY_SWITCH - private FileHandle fileHandle = new nn.fs.FileHandle(); + private FileHandle fileHandle = new nn.fs.FileHandle(); #endif - static object commitLock = new object(); + static object commitLock = new object(); - static bool bDirty = false; + static bool bDirty = false; - bool CommitSave() - { - lock (commitLock) - { + bool CommitSave() + { + lock (commitLock) + { #if UNITY_SWITCH && !UNITY_EDITOR // 阻止用户在保存时,退出游戏 Switch 条例 0080 @@ -39,242 +40,265 @@ public class AxiNSIO bDirty = false; return true; #else - return false; + return false; #endif - } + } - } + } - void SetCommitDirty() - { - lock (commitLock) - { - bDirty = true; - } - } + void SetCommitDirty() + { + lock (commitLock) + { + bDirty = true; + } + } - public void ApplyAutoCommit() - { - bool temp; - lock (commitLock) - { - temp = bDirty; - } + public void ApplyAutoCommit() + { + bool temp; + lock (commitLock) + { + temp = bDirty; + } - if (temp) - { - CommitSave(); - } - } + if (temp) + { + CommitSave(); + } + } - /// - /// 检查Path是否存在 - /// - /// - /// - public bool CheckPathExists(string filePath) - { + /// + /// 检查Path是否存在 + /// + /// + /// + public bool CheckPathExists(string filePath) + { #if !UNITY_SWITCH return false; #else - nn.fs.EntryType entryType = 0; - nn.Result result = nn.fs.FileSystem.GetEntryType(ref entryType, filePath); - //result.abortUnlessSuccess(); - //这个异常捕获。真的别扭 + nn.fs.EntryType entryType = 0; + nn.Result result = nn.fs.FileSystem.GetEntryType(ref entryType, filePath); + //result.abortUnlessSuccess(); + //这个异常捕获。真的别扭 - //日,FileSystem.ResultPathAlreadyExists 貌似不太行 - //return nn.fs.FileSystem.ResultPathAlreadyExists.Includes(result); - return !nn.fs.FileSystem.ResultPathNotFound.Includes(result); + //日,FileSystem.ResultPathAlreadyExists 貌似不太行 + //return nn.fs.FileSystem.ResultPathAlreadyExists.Includes(result); + return !nn.fs.FileSystem.ResultPathNotFound.Includes(result); #endif - } - /// - /// 检查Path是否不存在 - /// - /// - /// - public bool CheckPathNotFound(string filePath) - { + } + /// + /// 检查Path是否不存在 + /// + /// + /// + public bool CheckPathNotFound(string filePath) + { #if !UNITY_SWITCH return false; #else - nn.fs.EntryType entryType = 0; - nn.Result result = nn.fs.FileSystem.GetEntryType(ref entryType, filePath); - //这个异常捕获。真的别扭 - return nn.fs.FileSystem.ResultPathNotFound.Includes(result); + nn.fs.EntryType entryType = 0; + nn.Result result = nn.fs.FileSystem.GetEntryType(ref entryType, filePath); + //这个异常捕获。真的别扭 + return nn.fs.FileSystem.ResultPathNotFound.Includes(result); #endif - } - /// - /// 创建目录,目录存在也会返回true - /// - /// - /// - public bool CreateDir(string filePath) - { - lock (commitLock) - { + } + /// + /// 创建目录,目录存在也会返回true + /// + /// + /// + public bool CreateDir(string dirpath) + { + UnityEngine.Debug.Log($"CreateDir: {dirpath}"); + lock (commitLock) + { #if !UNITY_SWITCH return false; #else - // 使用封装函数检查和创建父目录 - if (!EnsureParentDirectory(filePath, true)) - { - UnityEngine.Debug.LogError($"无法确保父目录,文件写入取消: {filePath}"); - return false; - } - return true; + // 使用封装函数检查和创建父目录 + if (!EnsureParentDirectory(dirpath, true)) + { + UnityEngine.Debug.LogError($"无法确保父目录,文件写入取消: {dirpath}"); + return false; + } + return true; #endif - } - } + } + } - /// - /// 保存并创建文件(如果目录不存在回先自动创建目录) - /// - /// - /// - /// - public bool FileToSaveWithCreate(string filePath, System.IO.MemoryStream ms) - { - return FileToSaveWithCreate(filePath, ms.ToArray()); - } - /// - /// 保存并创建文件(如果目录不存在回先自动创建目录) - /// - /// - /// - /// - public AxiNSWait_FileToSaveByMSWithCreate FileToSaveWithCreateAsync(string filePath, System.IO.MemoryStream ms) - { - var wait = new AxiNSWait_FileToSaveByMSWithCreate(filePath, ms); - AxiNS.instance.wait.AddWait(wait); - return wait; - } + /// + /// 保存并创建文件(如果目录不存在回先自动创建目录) + /// + /// + /// + /// + public bool FileToSaveWithCreate(string filePath, System.IO.MemoryStream ms) + { + return FileToSaveWithCreate(filePath, ms.ToArray()); + } + /// + /// 保存并创建文件(如果目录不存在回先自动创建目录) + /// + /// + /// + /// + public AxiNSWait_FileToSaveByMSWithCreate FileToSaveWithCreateAsync(string filePath, System.IO.MemoryStream ms) + { + var wait = new AxiNSWait_FileToSaveByMSWithCreate(filePath, ms); + AxiNS.instance.wait.AddWait(wait); + return wait; + } - /// - /// 保存并创建文件(如果目录不存在回先自动创建目录) - /// - /// - /// - /// 是否立即Commit到物理存储 - /// - public bool FileToSaveWithCreate(string filePath, byte[] data, bool immediatelyCommit = true) - { - lock (commitLock) - { + /// + /// 保存并创建文件(如果目录不存在回先自动创建目录) + /// + /// + /// + /// 是否立即Commit到物理存储 + /// + public bool FileToSaveWithCreate(string filePath, byte[] data, bool immediatelyCommit = true) + { + UnityEngine.Debug.Log($"FileToSaveWithCreate: {filePath}"); + lock (commitLock) + { #if !UNITY_SWITCH return false; #else - if (!AxiNS.instance.mount.SaveIsMount) - { - UnityEngine.Debug.LogError($"Save 尚未挂载,无法存储 {filePath}"); - return false; - } + if (!AxiNS.instance.mount.SaveIsMount) + { + UnityEngine.Debug.LogError($"Save 尚未挂载,无法存储 {filePath}"); + return false; + } + + nn.Result result; + + //取出父级目录 + string dirpath = string.Empty; + //string filePath = "save:/AxibugEmu/Caches/Texture/516322966"; + string mountRoot = null; + int colonSlashIndex = filePath.IndexOf(":/"); + if (colonSlashIndex > 0) + mountRoot = filePath.Substring(0, colonSlashIndex + 1); // 例如 "save:" + + int lastSlashIndex = filePath.LastIndexOf('/'); + if (lastSlashIndex >= 0) + { + string parent = filePath.Substring(0, lastSlashIndex); + if (mountRoot != null && !parent.Equals(mountRoot, StringComparison.OrdinalIgnoreCase)) + dirpath = parent; + } + + + if (!string.IsNullOrWhiteSpace(dirpath)) + { + // 使用封装函数检查和创建父目录 + if (!EnsureParentDirectory(dirpath, true)) + { + UnityEngine.Debug.LogError($"无法确保父目录,文件写入取消: {filePath}"); + return false; + } + } + + //string directoryPath = System.IO.Path.GetDirectoryName(filePath.Replace(save_path, "")); + //string fullDirectoryPath = $"{save_path}{directoryPath}"; + //UnityEngine.Debug.Log($"检查父目录: {fullDirectoryPath}"); + + //nn.fs.EntryType entryType = 0; + //result = nn.fs.FileSystem.GetEntryType(ref entryType, fullDirectoryPath); + //if (!result.IsSuccess() && nn.fs.FileSystem.ResultPathNotFound.Includes(result)) + //{ + // UnityEngine.Debug.Log($"父目录 {fullDirectoryPath} 不存在,尝试创建 (判断依据 result=>{result.ToString()})"); + // result = nn.fs.Directory.Create(fullDirectoryPath); + // if (!result.IsSuccess()) + // { + // UnityEngine.Debug.LogError($"创建父目录失败: {result.GetErrorInfo()}"); + // return false; + // } + // UnityEngine.Debug.Log($"父目录 {fullDirectoryPath} 创建成功"); + //} + //else if (result.IsSuccess() && entryType != nn.fs.EntryType.Directory) + //{ + // UnityEngine.Debug.LogError($"路径 {fullDirectoryPath} 已存在,但不是目录"); + // return false; + //} + //else if (!result.IsSuccess()) + //{ + // UnityEngine.Debug.LogError($"检查父目录失败: {result.GetErrorInfo()}"); + // return false; + //} - nn.Result result; #if UNITY_SWITCH && !UNITY_EDITOR // 阻止用户在保存时,退出游戏 // Switch 条例 0080 UnityEngine.Switch.Notification.EnterExitRequestHandlingSection(); #endif - // 使用封装函数检查和创建父目录 - if (!EnsureParentDirectory(filePath, true)) - { - UnityEngine.Debug.LogError($"无法确保父目录,文件写入取消: {filePath}"); - return false; - } + if (CheckPathNotFound(filePath)) + { + UnityEngine.Debug.Log($"文件({filePath})不存在需要创建"); + result = nn.fs.File.Create(filePath, data.Length); //this makes a file the size of your save journal. You may want to make a file smaller than this. + //result.abortUnlessSuccess(); + if (!result.IsSuccess()) + { + UnityEngine.Debug.LogError($"创建文件失败 {filePath} : " + result.GetErrorInfo()); + return false; + } + //读取文件Handle + result = File.Open(ref fileHandle, filePath, OpenFileMode.Write); + } + else + { + //读取文件Handle + result = File.Open(ref fileHandle, filePath, OpenFileMode.Write); + long currsize = 0; + File.GetSize(ref currsize, fileHandle); + if (currsize == data.Length) + { + UnityEngine.Debug.Log($"文件({filePath})存在,长度一致,不用重新创建"); + } + else + { + UnityEngine.Debug.Log($"文件({filePath})存在,长度不一致,先删除再重建"); + nn.fs.File.Close(fileHandle); + //删除 + File.Delete(filePath); + //重新创建 + result = nn.fs.File.Create(filePath, data.Length); + if (!result.IsSuccess()) + { + UnityEngine.Debug.LogError($"创建文件失败 {filePath} : " + result.GetErrorInfo()); + return false; + } + //重新读取文件Handle + result = File.Open(ref fileHandle, filePath, OpenFileMode.Write); + } + } - //string directoryPath = System.IO.Path.GetDirectoryName(filePath.Replace(save_path, "")); - //string fullDirectoryPath = $"{save_path}{directoryPath}"; - //UnityEngine.Debug.Log($"检查父目录: {fullDirectoryPath}"); + // //OpenFileMode.AllowAppend 好像不可用 + // //result = File.Open(ref fileHandle, filePath, OpenFileMode.AllowAppend); + // result = File.Open(ref fileHandle, filePath, OpenFileMode.Write); - //nn.fs.EntryType entryType = 0; - //result = nn.fs.FileSystem.GetEntryType(ref entryType, fullDirectoryPath); - //if (!result.IsSuccess() && nn.fs.FileSystem.ResultPathNotFound.Includes(result)) - //{ - // UnityEngine.Debug.Log($"父目录 {fullDirectoryPath} 不存在,尝试创建 (判断依据 result=>{result.ToString()})"); - // result = nn.fs.Directory.Create(fullDirectoryPath); - // if (!result.IsSuccess()) - // { - // UnityEngine.Debug.LogError($"创建父目录失败: {result.GetErrorInfo()}"); - // return false; - // } - // UnityEngine.Debug.Log($"父目录 {fullDirectoryPath} 创建成功"); - //} - //else if (result.IsSuccess() && entryType != nn.fs.EntryType.Directory) - //{ - // UnityEngine.Debug.LogError($"路径 {fullDirectoryPath} 已存在,但不是目录"); - // return false; - //} - //else if (!result.IsSuccess()) - //{ - // UnityEngine.Debug.LogError($"检查父目录失败: {result.GetErrorInfo()}"); - // return false; - //} + //result.abortUnlessSuccess(); + if (!result.IsSuccess()) + { + UnityEngine.Debug.LogError($"失败 File.Open(ref filehandle, {filePath}, OpenFileMode.Write): " + result.GetErrorInfo()); + return false; + } + UnityEngine.Debug.Log($"成功 File.Open(ref filehandle, {filePath}, OpenFileMode.Write)"); - if (CheckPathNotFound(filePath)) - { - UnityEngine.Debug.Log($"文件({filePath})不存在需要创建"); - result = nn.fs.File.Create(filePath, data.Length); //this makes a file the size of your save journal. You may want to make a file smaller than this. - //result.abortUnlessSuccess(); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"创建文件失败 {filePath} : " + result.GetErrorInfo()); - return false; - } - //读取文件Handle - result = File.Open(ref fileHandle, filePath, OpenFileMode.Write); - } - else - { - //读取文件Handle - result = File.Open(ref fileHandle, filePath, OpenFileMode.Write); - long currsize = 0; - File.GetSize(ref currsize, fileHandle); - if (currsize == data.Length) - { - UnityEngine.Debug.Log($"文件({filePath})存在,长度一致,不用重新创建"); - } - else - { - UnityEngine.Debug.Log($"文件({filePath})存在,长度不一致,先删除再重建"); - nn.fs.File.Close(fileHandle); - //删除 - File.Delete(filePath); - //重新创建 - result = nn.fs.File.Create(filePath, data.Length); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"创建文件失败 {filePath} : " + result.GetErrorInfo()); - return false; - } - //重新读取文件Handle - result = File.Open(ref fileHandle, filePath, OpenFileMode.Write); - } - } + //nn.fs.WriteOption.Flush 应该就是覆盖写入 + result = nn.fs.File.Write(fileHandle, 0, data, data.Length, nn.fs.WriteOption.Flush); // Writes and flushes the write at the same time + //result.abortUnlessSuccess(); + if (!result.IsSuccess()) + { + UnityEngine.Debug.LogError("写入文件失败: " + result.GetErrorInfo()); + return false; + } + UnityEngine.Debug.Log("写入文件成功: " + filePath); - // //OpenFileMode.AllowAppend 好像不可用 - // //result = File.Open(ref fileHandle, filePath, OpenFileMode.AllowAppend); - // result = File.Open(ref fileHandle, filePath, OpenFileMode.Write); - - //result.abortUnlessSuccess(); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"失败 File.Open(ref filehandle, {filePath}, OpenFileMode.Write): " + result.GetErrorInfo()); - return false; - } - UnityEngine.Debug.Log($"成功 File.Open(ref filehandle, {filePath}, OpenFileMode.Write)"); - - //nn.fs.WriteOption.Flush 应该就是覆盖写入 - result = nn.fs.File.Write(fileHandle, 0, data, data.Length, nn.fs.WriteOption.Flush); // Writes and flushes the write at the same time - //result.abortUnlessSuccess(); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError("写入文件失败: " + result.GetErrorInfo()); - return false; - } - UnityEngine.Debug.Log("写入文件成功: " + filePath); - - nn.fs.File.Close(fileHandle); + nn.fs.File.Close(fileHandle); #if UNITY_SWITCH && !UNITY_EDITOR @@ -282,56 +306,56 @@ public class AxiNSIO UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif - if (immediatelyCommit) - { - //必须得提交,否则没有真实写入 - return CommitSave(); - } - else - { - SetCommitDirty(); - return true; - } + if (immediatelyCommit) + { + //必须得提交,否则没有真实写入 + return CommitSave(); + } + else + { + SetCommitDirty(); + return true; + } #endif - } - } - /// - /// 保存并创建文件(如果目录不存在回先自动创建目录) - /// - /// - /// - /// - public AxiNSWait_FileToSaveWithCreate FileToSaveWithCreateAsync(string filePath, byte[] data) - { - var wait = new AxiNSWait_FileToSaveWithCreate(filePath, data); - AxiNS.instance.wait.AddWait(wait); - return wait; - } - public byte[] LoadSwitchDataFile(string filename) - { - byte[] outputData; - LoadSwitchDataFile(filename, out outputData); - return outputData; - } + } + } + /// + /// 保存并创建文件(如果目录不存在回先自动创建目录) + /// + /// + /// + /// + public AxiNSWait_FileToSaveWithCreate FileToSaveWithCreateAsync(string filePath, byte[] data) + { + var wait = new AxiNSWait_FileToSaveWithCreate(filePath, data); + AxiNS.instance.wait.AddWait(wait); + return wait; + } + public byte[] LoadSwitchDataFile(string filename) + { + byte[] outputData; + LoadSwitchDataFile(filename, out outputData); + return outputData; + } - public bool LoadSwitchDataFile(string filename, ref System.IO.MemoryStream ms) - { - byte[] outputData; - if (LoadSwitchDataFile(filename, out outputData)) - { - using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms)) - { - writer.Write(outputData); - } - return true; - } - return false; - } - public bool LoadSwitchDataFile(string filename, out byte[] outputData) - { + public bool LoadSwitchDataFile(string filename, ref System.IO.MemoryStream ms) + { + byte[] outputData; + if (LoadSwitchDataFile(filename, out outputData)) + { + using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms)) + { + writer.Write(outputData); + } + return true; + } + return false; + } + public bool LoadSwitchDataFile(string filename, out byte[] outputData) + { #if !UNITY_SWITCH || UNITY_EDITOR - outputData = null; - return false; + outputData = null; + return false; #else outputData = null; if (!AxiNS.instance.mount.SaveIsMount) @@ -379,104 +403,104 @@ public class AxiNSIO outputData = loadedData; return true; #endif - } - public AxiNSWait_LoadSwitchDataFile LoadSwitchDataFileAsync(string filename) - { - var wait = new AxiNSWait_LoadSwitchDataFile(filename); - AxiNS.instance.wait.AddWait(wait); - return wait; - } + } + public AxiNSWait_LoadSwitchDataFile LoadSwitchDataFileAsync(string filename) + { + var wait = new AxiNSWait_LoadSwitchDataFile(filename); + AxiNS.instance.wait.AddWait(wait); + return wait; + } - public bool GetDirectoryFiles(string path, out string[] entrys) - { + public bool GetDirectoryFiles(string path, out string[] entrys) + { #if !UNITY_SWITCH || UNITY_EDITOR - entrys = null; - return false; + entrys = null; + return false; #else return GetDirectoryEntrys(path,nn.fs.OpenDirectoryMode.File,out entrys); #endif - } + } - public bool GetDirectoryDirs(string path, out string[] entrys) - { + public bool GetDirectoryDirs(string path, out string[] entrys) + { #if !UNITY_SWITCH || UNITY_EDITOR - entrys = null; - return false; + entrys = null; + return false; #else return GetDirectoryEntrys(path, nn.fs.OpenDirectoryMode.Directory, out entrys); #endif - } + } #if UNITY_SWITCH - public bool GetDirectoryEntrys(string path, nn.fs.OpenDirectoryMode type, out string[] entrys) - { - nn.fs.DirectoryHandle eHandle = new nn.fs.DirectoryHandle(); - nn.Result result = nn.fs.Directory.Open(ref eHandle, path, type); - if (nn.fs.FileSystem.ResultPathNotFound.Includes(result)) - { - UnityEngine.Debug.Log($"目录 {path} 不存在"); - entrys = null; - return false; - } - long entryCount = 0; - nn.fs.Directory.GetEntryCount(ref entryCount, eHandle); - nn.fs.DirectoryEntry[] entries = new nn.fs.DirectoryEntry[entryCount]; - long actualEntries = 0; - nn.fs.Directory.Read(ref actualEntries, entries, eHandle, entryCount); + public bool GetDirectoryEntrys(string path, nn.fs.OpenDirectoryMode type, out string[] entrys) + { + nn.fs.DirectoryHandle eHandle = new nn.fs.DirectoryHandle(); + nn.Result result = nn.fs.Directory.Open(ref eHandle, path, type); + if (nn.fs.FileSystem.ResultPathNotFound.Includes(result)) + { + UnityEngine.Debug.Log($"目录 {path} 不存在"); + entrys = null; + return false; + } + long entryCount = 0; + nn.fs.Directory.GetEntryCount(ref entryCount, eHandle); + nn.fs.DirectoryEntry[] entries = new nn.fs.DirectoryEntry[entryCount]; + long actualEntries = 0; + nn.fs.Directory.Read(ref actualEntries, entries, eHandle, entryCount); - entrys = new string[actualEntries]; - for (int i = 0; i < actualEntries; i++) - { - entrys[i] = System.IO.Path.Combine(path, entries[i].name); - } - nn.fs.Directory.Close(eHandle); - return true; - } + entrys = new string[actualEntries]; + for (int i = 0; i < actualEntries; i++) + { + entrys[i] = System.IO.Path.Combine(path, entries[i].name); + } + nn.fs.Directory.Close(eHandle); + return true; + } #endif - public bool GetDirectoryEntrysFullRecursion(string path, out string[] entrys) - { + public bool GetDirectoryEntrysFullRecursion(string path, out string[] entrys) + { #if UNITY_SWITCH - nn.fs.DirectoryHandle eHandle = new nn.fs.DirectoryHandle(); - nn.Result result = nn.fs.Directory.Open(ref eHandle, path, OpenDirectoryMode.All); - if (nn.fs.FileSystem.ResultPathNotFound.Includes(result)) - { - UnityEngine.Debug.Log($"目录 {path} 不存在"); - entrys = null; - return false; - } - long entryCount = 0; - nn.fs.Directory.GetEntryCount(ref entryCount, eHandle); - nn.fs.DirectoryEntry[] entries = new nn.fs.DirectoryEntry[entryCount]; - long actualEntries = 0; - nn.fs.Directory.Read(ref actualEntries, entries, eHandle, entryCount); + nn.fs.DirectoryHandle eHandle = new nn.fs.DirectoryHandle(); + nn.Result result = nn.fs.Directory.Open(ref eHandle, path, OpenDirectoryMode.All); + if (nn.fs.FileSystem.ResultPathNotFound.Includes(result)) + { + UnityEngine.Debug.Log($"目录 {path} 不存在"); + entrys = null; + return false; + } + long entryCount = 0; + nn.fs.Directory.GetEntryCount(ref entryCount, eHandle); + nn.fs.DirectoryEntry[] entries = new nn.fs.DirectoryEntry[entryCount]; + long actualEntries = 0; + nn.fs.Directory.Read(ref actualEntries, entries, eHandle, entryCount); - List temp = new List(); - for (int i = 0; i < actualEntries; i++) - { - string singlePath = System.IO.Path.Combine(path, entries[i].name); - temp.Add(singlePath); - if (entries[i].entryType == EntryType.Directory && GetDirectoryEntrysFullRecursion(singlePath, out string[] singleEntryList)) - { - temp.AddRange(singleEntryList); - } - } - nn.fs.Directory.Close(eHandle); - entrys = temp.ToArray(); - return true; + List temp = new List(); + for (int i = 0; i < actualEntries; i++) + { + string singlePath = System.IO.Path.Combine(path, entries[i].name); + temp.Add(singlePath); + if (entries[i].entryType == EntryType.Directory && GetDirectoryEntrysFullRecursion(singlePath, out string[] singleEntryList)) + { + temp.AddRange(singleEntryList); + } + } + nn.fs.Directory.Close(eHandle); + entrys = temp.ToArray(); + return true; #else entrys = null; return false; #endif - } + } - public IEnumerable EnumerateFiles(string path, string searchPattern) - { + public IEnumerable EnumerateFiles(string path, string searchPattern) + { #if !UNITY_SWITCH || UNITY_EDITOR - yield break; + yield break; #else // 将通配符转换为正则表达式(支持*和?) var regexPattern = "^" + @@ -500,10 +524,10 @@ public class AxiNSIO } } #endif - } + } - public bool DeletePathFile(string filename) - { + public bool DeletePathFile(string filename) + { #if !UNITY_SWITCH return false; #else @@ -515,32 +539,32 @@ public class AxiNSIO UnityEngine.Switch.Notification.EnterExitRequestHandlingSection(); #endif - if (CheckPathNotFound(filename)) - return false; - nn.Result result; - result = nn.fs.File.Delete(filename); - if (result.IsSuccess() == false) - { - UnityEngine.Debug.LogError($"nn.fs.File.Delete 失败 {filename} : result=>{result.GetErrorInfo()}"); - return false; - } + if (CheckPathNotFound(filename)) + return false; + nn.Result result; + result = nn.fs.File.Delete(filename); + if (result.IsSuccess() == false) + { + UnityEngine.Debug.LogError($"nn.fs.File.Delete 失败 {filename} : result=>{result.GetErrorInfo()}"); + return false; + } #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif - return CommitSave(); + return CommitSave(); #endif - } - public AxiNSWait_DeletePathFile DeletePathFileAsync(string filename) - { - var wait = new AxiNSWait_DeletePathFile(filename); - AxiNS.instance.wait.AddWait(wait); - return wait; - } - public bool DeletePathDir(string filename) - { + } + public AxiNSWait_DeletePathFile DeletePathFileAsync(string filename) + { + var wait = new AxiNSWait_DeletePathFile(filename); + AxiNS.instance.wait.AddWait(wait); + return wait; + } + public bool DeletePathDir(string filename) + { #if !UNITY_SWITCH return false; #else @@ -551,31 +575,31 @@ public class AxiNSIO UnityEngine.Switch.Notification.EnterExitRequestHandlingSection(); #endif - if (CheckPathNotFound(filename)) - return false; - nn.Result result; - result = nn.fs.Directory.Delete(filename); - if (result.IsSuccess() == false) - { - UnityEngine.Debug.LogError($"nn.fs.File.Delete 失败 {filename} : result=>{result.GetErrorInfo()}"); - return false; - } + if (CheckPathNotFound(filename)) + return false; + nn.Result result; + result = nn.fs.Directory.Delete(filename); + if (result.IsSuccess() == false) + { + UnityEngine.Debug.LogError($"nn.fs.File.Delete 失败 {filename} : result=>{result.GetErrorInfo()}"); + return false; + } #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif - return CommitSave(); + return CommitSave(); #endif - } - public AxiNSWait_DeletePathDir DeletePathDirAsync(string filename) - { - var wait = new AxiNSWait_DeletePathDir(filename); - AxiNS.instance.wait.AddWait(wait); - return wait; - } - public bool DeletePathDirRecursively(string filename) - { + } + public AxiNSWait_DeletePathDir DeletePathDirAsync(string filename) + { + var wait = new AxiNSWait_DeletePathDir(filename); + AxiNS.instance.wait.AddWait(wait); + return wait; + } + public bool DeletePathDirRecursively(string filename) + { #if !UNITY_SWITCH return false; #else @@ -586,37 +610,37 @@ public class AxiNSIO UnityEngine.Switch.Notification.EnterExitRequestHandlingSection(); #endif - if (CheckPathNotFound(filename)) - return false; - nn.Result result; - result = nn.fs.Directory.DeleteRecursively(filename); - if (result.IsSuccess() == false) - { - UnityEngine.Debug.LogError($"nn.fs.File.Recursively 失败 {filename} : result=>{result.GetErrorInfo()}"); - return false; - } + if (CheckPathNotFound(filename)) + return false; + nn.Result result; + result = nn.fs.Directory.DeleteRecursively(filename); + if (result.IsSuccess() == false) + { + UnityEngine.Debug.LogError($"nn.fs.File.Recursively 失败 {filename} : result=>{result.GetErrorInfo()}"); + return false; + } #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif - return CommitSave(); + return CommitSave(); #endif - } - public AxiNSWait_DeletePathDirRecursively DeletePathDirRecursivelyAsync(string filename) - { - var wait = new AxiNSWait_DeletePathDirRecursively(filename); - AxiNS.instance.wait.AddWait(wait); - return wait; - } + } + public AxiNSWait_DeletePathDirRecursively DeletePathDirRecursivelyAsync(string filename) + { + var wait = new AxiNSWait_DeletePathDirRecursively(filename); + AxiNS.instance.wait.AddWait(wait); + return wait; + } - /// - /// 递归删除目录 - /// - /// - /// - public bool DeleteRecursivelyPathDir(string filename) - { + /// + /// 递归删除目录 + /// + /// + /// + public bool DeleteRecursivelyPathDir(string filename) + { #if !UNITY_SWITCH return false; #else @@ -627,31 +651,31 @@ public class AxiNSIO UnityEngine.Switch.Notification.EnterExitRequestHandlingSection(); #endif - if (CheckPathNotFound(filename)) - return false; - nn.Result result; - result = nn.fs.Directory.DeleteRecursively(filename); - if (result.IsSuccess() == false) - { - UnityEngine.Debug.LogError($"nn.fs.File.DeleteRecursively 失败 {filename} : result=>{result.GetErrorInfo()}"); - return false; - } + if (CheckPathNotFound(filename)) + return false; + nn.Result result; + result = nn.fs.Directory.DeleteRecursively(filename); + if (result.IsSuccess() == false) + { + UnityEngine.Debug.LogError($"nn.fs.File.DeleteRecursively 失败 {filename} : result=>{result.GetErrorInfo()}"); + return false; + } #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif - return CommitSave(); + return CommitSave(); #endif - } + } - /// - /// 递归删除情况 - /// - /// - /// - public bool CleanRecursivelyPathDir(string filename) - { + /// + /// 递归删除情况 + /// + /// + /// + public bool CleanRecursivelyPathDir(string filename) + { #if !UNITY_SWITCH return false; #else @@ -662,26 +686,26 @@ public class AxiNSIO UnityEngine.Switch.Notification.EnterExitRequestHandlingSection(); #endif - if (CheckPathNotFound(filename)) - return false; - nn.Result result; - result = nn.fs.Directory.CleanRecursively(filename); - if (result.IsSuccess() == false) - { - UnityEngine.Debug.LogError($"nn.fs.File.DeleteRecursively 失败 {filename} : result=>{result.GetErrorInfo()}"); - return false; - } + if (CheckPathNotFound(filename)) + return false; + nn.Result result; + result = nn.fs.Directory.CleanRecursively(filename); + if (result.IsSuccess() == false) + { + UnityEngine.Debug.LogError($"nn.fs.File.DeleteRecursively 失败 {filename} : result=>{result.GetErrorInfo()}"); + return false; + } #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif - return CommitSave(); + return CommitSave(); #endif - } + } - public bool RenameDir(string oldpath, string newpath) - { + public bool RenameDir(string oldpath, string newpath) + { #if !UNITY_SWITCH return false; #else @@ -692,146 +716,364 @@ public class AxiNSIO UnityEngine.Switch.Notification.EnterExitRequestHandlingSection(); #endif - if (CheckPathNotFound(oldpath)) - return false; + if (CheckPathNotFound(oldpath)) + return false; - nn.Result result; - result = nn.fs.Directory.Rename(oldpath, newpath); - if (result.IsSuccess() == false) - { - UnityEngine.Debug.LogError($"nn.fs.File.Rename 失败 {oldpath} to {newpath} : result=>{result.GetErrorInfo()}"); - return false; - } + nn.Result result; + result = nn.fs.Directory.Rename(oldpath, newpath); + if (result.IsSuccess() == false) + { + UnityEngine.Debug.LogError($"nn.fs.File.Rename 失败 {oldpath} to {newpath} : result=>{result.GetErrorInfo()}"); + return false; + } #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif - return CommitSave(); + return CommitSave(); #endif - } - bool EnsureParentDirectory(string filePath, bool bAutoCreateDir = true) - { + } + + bool CreateLoopDir(string path) + { + // 检查路径是否存在及其类型 + nn.fs.EntryType entryType = 0; + nn.Result result; + List needcreatedirs = new List(); + string node = path; + while (true) + { + if (string.IsNullOrEmpty(node) || node.EndsWith(":/")) + break; + + + if (!CheckPathNotFound(node)) + needcreatedirs.Insert(0, node); + else + break; + + result = nn.fs.FileSystem.GetEntryType(ref entryType, node); + if (!result.IsSuccess()) + needcreatedirs.Insert(0, node); + else + break;//文件已存在 + + node = System.IO.Path.GetDirectoryName(node); + } + + for (int i = 0; i < needcreatedirs.Count; i++) + { + UnityEngine.Debug.LogError($"需要创建的目录: {needcreatedirs[i]}"); + } + + for (int i = 0; i < needcreatedirs.Count; i++) + { + //result = nn.fs.Directory.Create(needcreatedirs[i]); + //if (!result.IsSuccess()) + //{ + // UnityEngine.Debug.LogError($"创建父目录失败: {result.GetErrorInfo()}"); + // return false; + //} + //UnityEngine.Debug.Log($"父目录 {needcreatedirs[i]} 创建成功"); + //CommitSave(); + } + + return false; + return true; + } + + + /// + /// 解析路径并获取其所有父级目录(从直接父目录到根目录),并排除存储设备挂载根节点(如"save:"或"sd:")。 + /// 专为Switch平台设计,正确处理如"save:/"或"sd:/"开头的路径。 + /// + /// 输入的绝对路径 + /// 输出参数,解析出的最直接目录(文件所在目录或目录自身) + /// 输出参数,从直接父目录到挂载点下一级的列表(不包含挂载根节点) + /// 操作是否成功(路径格式基本有效) + public bool TryGetDirectoryAndParentsExcludingRoot(string inputPath, out string resolvedDirectory, out List parentDirectories) + { + // 捕获路径中包含非法字符引发的异常 + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->{inputPath}"); + resolvedDirectory = null; + parentDirectories = new List(); + + if (string.IsNullOrWhiteSpace(inputPath)) + { + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->string.IsNullOrWhiteSpace({inputPath})==false"); + return false; + } + + string normalizedPath = inputPath.Replace('\\', '/').Trim(); // 统一使用正斜杠 + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->normalizedPath=>{normalizedPath}"); + try + { + // 1. 判断路径类型并解析出最直接的目标目录 + bool isLikelyFile = false; + + if (normalizedPath.EndsWith("/")) + { + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->normalizedPath.EndsWith(\"/\") == true"); + resolvedDirectory = normalizedPath.TrimEnd('/'); + } + else + { + int lastSeparatorIndex = normalizedPath.LastIndexOf('/'); + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->lastSeparatorIndex->{lastSeparatorIndex}"); + string lastPart = (lastSeparatorIndex >= 0) ? normalizedPath.Substring(lastSeparatorIndex + 1) : normalizedPath; + + if (string.IsNullOrEmpty(lastPart) || lastPart.Equals("..") || !lastPart.Contains(".")) + { + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->step1"); + resolvedDirectory = normalizedPath; + } + else + { + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->step2"); + isLikelyFile = true; + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->lastSeparatorIndex=>{lastSeparatorIndex}"); + if (lastSeparatorIndex >= 0) + { + resolvedDirectory = normalizedPath.Substring(0, lastSeparatorIndex); + } + else + { + resolvedDirectory = normalizedPath; // 可能是根目录下的文件,但这种情况在Switch特殊路径中较少 + } + } + } + + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->resolvedDirectory=>{resolvedDirectory}"); + if (string.IsNullOrEmpty(resolvedDirectory)) + { + UnityEngine.Debug.LogError($"TryGetDirectoryAndParentsExcludingRoot->string.IsNullOrEmpty(resolvedDirectory) == false"); + return false; + } + + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->step3"); + // 2. 提取并检查挂载根节点(如 "save:" 或 "sd:") + string mountRoot = null; + int colonSlashIndex = resolvedDirectory.IndexOf(":/"); + if (colonSlashIndex > 0) + { + mountRoot = resolvedDirectory.Substring(0, colonSlashIndex + 1); // 例如 "save:" + } + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->mountRoot=>{mountRoot}"); + + // 检查挂载状态 + if (!IsMountPointAccessible(mountRoot + "/")) + { + UnityEngine.Debug.LogError($"挂载点 {mountRoot + "/"} 未挂载,无法操作路径 {inputPath}"); + return false; + } + + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->step4"); + // 3. 手动分割路径,收集父目录,并在到达挂载根节点时停止 + string currentPath = resolvedDirectory; + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->currentPath=>{currentPath}"); + while (!string.IsNullOrEmpty(currentPath)) + { + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->step5"); + // 检查当前路径是否已经是挂载根节点(例如 "save:") + if (mountRoot != null && currentPath.Equals(mountRoot, StringComparison.OrdinalIgnoreCase)) + { + break; // 停止添加,不将挂载根节点加入父目录列表 + } + + parentDirectories.Add(currentPath); // 将当前层级的路径加入列表 + + int lastSlashIndex = currentPath.LastIndexOf('/'); + if (lastSlashIndex < 0) + { + break; // 没有分隔符了,跳出循环 + } + + string nextParent = currentPath.Substring(0, lastSlashIndex); + + // 检查下一级父目录是否就是挂载根节点(例如 "save:"),如果是,则停止 + if (mountRoot != null && nextParent.Equals(mountRoot, StringComparison.OrdinalIgnoreCase)) + { + // 可以选择是否将 mountRoot 加入列表,这里根据需求不加入 + break; + } + + currentPath = nextParent; + } + UnityEngine.Debug.Log($"TryGetDirectoryAndParentsExcludingRoot->step6 True Return"); + + return true; + } + catch (ArgumentException ex) + { + // 捕获路径中包含非法字符引发的异常 + UnityEngine.Debug.LogError($"路径中包含非法字符: {ex.Message}"); + return false; + } + } + + bool EnsureParentDirectory(string filePath, bool bAutoCreateDir = true) + { #if !UNITY_SWITCH return false; #else - // 参数校验 - if (string.IsNullOrEmpty(filePath)) - { - UnityEngine.Debug.LogError($"无效参数:filePath={filePath}"); - return false; - } + //// 参数校验 + //if (string.IsNullOrEmpty(filePath)) + //{ + // UnityEngine.Debug.LogError($"无效参数:filePath={filePath}"); + // return false; + //} - // 提取路径前缀(如 save:/、sd:/) - int prefixEndIndex = filePath.IndexOf(":/"); - if (prefixEndIndex == -1) - { - UnityEngine.Debug.LogError($"文件路径 {filePath} 格式无效,未找到 ':/' 前缀"); - return false; - } - string pathPrefix = filePath.Substring(0, prefixEndIndex + 2); // 提取前缀,例如 "save:/" - string relativePath = filePath.Substring(prefixEndIndex + 2); // 移除前缀,得到相对路径 + //// 提取路径前缀(如 save:/、sd:/) + //int prefixEndIndex = filePath.IndexOf(":/"); + //if (prefixEndIndex == -1) + //{ + // UnityEngine.Debug.LogError($"文件路径 {filePath} 格式无效,未找到 ':/' 前缀"); + // return false; + //} + //string pathPrefix = filePath.Substring(0, prefixEndIndex + 2); // 提取前缀,例如 "save:/" + //string relativePath = filePath.Substring(prefixEndIndex + 2); // 移除前缀,得到相对路径 - // 检查挂载状态 - if (!IsMountPointAccessible(pathPrefix)) - { - UnityEngine.Debug.LogError($"挂载点 {pathPrefix} 未挂载,无法操作路径 {filePath}"); - return false; - } + //// 检查挂载状态 + //if (!IsMountPointAccessible(pathPrefix)) + //{ + // UnityEngine.Debug.LogError($"挂载点 {pathPrefix} 未挂载,无法操作路径 {filePath}"); + // return false; + //} - // 提取父目录路径 - string directoryPath = System.IO.Path.GetDirectoryName(relativePath); // 获取父目录相对路径 - if (string.IsNullOrEmpty(directoryPath)) - { - UnityEngine.Debug.Log($"文件路径 {filePath} 无需创建父目录(位于根目录)"); - return true; // 根目录无需创建 - } + //// 提取父目录路径 + //string directoryPath = System.IO.Path.GetDirectoryName(relativePath); // 获取父目录相对路径 + //UnityEngine.Debug.Log($"提取 {relativePath} 的 父级路径:{directoryPath}"); + //if (string.IsNullOrEmpty(directoryPath)) + //{ + // UnityEngine.Debug.Log($"文件路径 {filePath} 无需创建父目录(位于根目录)"); + // return true; // 根目录无需创建 + //} - string fullDirectoryPath = $"{pathPrefix}{directoryPath}"; // 拼接完整父目录路径 - UnityEngine.Debug.Log($"检查父目录: {fullDirectoryPath}"); + //string fullDirectoryPath = $"{pathPrefix}{directoryPath}"; // 拼接完整父目录路径 - // 检查路径是否存在及其类型 - nn.fs.EntryType entryType = 0; - nn.Result result = nn.fs.FileSystem.GetEntryType(ref entryType, fullDirectoryPath); - if (!result.IsSuccess() && nn.fs.FileSystem.ResultPathNotFound.Includes(result)) - { - if (bAutoCreateDir) - { - // 路径不存在,尝试创建 - UnityEngine.Debug.Log($"父目录 {fullDirectoryPath} 不存在,尝试创建 (判断依据 result=>{result.ToString()})"); - result = nn.fs.Directory.Create(fullDirectoryPath); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"创建父目录失败: {result.GetErrorInfo()}"); - return false; - } - UnityEngine.Debug.Log($"父目录 {fullDirectoryPath} 创建成功"); - return true; - } - return false; - } - else if (result.IsSuccess() && entryType != nn.fs.EntryType.Directory) - { - // 路径存在,但不是目录 - UnityEngine.Debug.LogError($"路径 {fullDirectoryPath} 已存在,但不是目录"); - return false; - } - else if (!result.IsSuccess()) - { - // 其他错误 - UnityEngine.Debug.LogError($"检查父目录失败: {result.GetErrorInfo()}"); - return false; - } - // 路径存在且是目录 - UnityEngine.Debug.Log($"父目录 {fullDirectoryPath} 已存在且有效"); - return true; + + if (!TryGetDirectoryAndParentsExcludingRoot(filePath, out string fullDirectoryPath, out List parentDirectories)) + { + UnityEngine.Debug.LogError($"TryGetDirectoryAndParentsExcludingRoot 操作失败:{filePath}"); + return false; + } + + UnityEngine.Debug.Log($"检查父目录: {fullDirectoryPath}"); + + // 检查路径是否存在及其类型 + nn.fs.EntryType entryType = 0; + nn.Result result = nn.fs.FileSystem.GetEntryType(ref entryType, fullDirectoryPath); + if (!result.IsSuccess() && nn.fs.FileSystem.ResultPathNotFound.Includes(result)) + { + if (bAutoCreateDir) + { + // 路径不存在,尝试创建 + UnityEngine.Debug.Log($"父目录 {fullDirectoryPath} 不存在,尝试创建 (判断依据 result=>{result.ToString()})"); + + for (int i = parentDirectories.Count - 1; i >= 0; i--) + { + UnityEngine.Debug.Log($">>待检查目录: {parentDirectories[i]}"); + } + + for (int i = parentDirectories.Count - 1; i >= 0; i--) + { + string dir = parentDirectories[i]; + if (CheckPathNotFound(dir)) + { + UnityEngine.Debug.Log($"需要创建的目录: {dir}"); + result = nn.fs.Directory.Create(dir); + if (!result.IsSuccess()) + { + UnityEngine.Debug.LogError($"创建父 {dir} 目录失败: {result.GetErrorInfo()}"); + return false; + } + UnityEngine.Debug.Log($"父目录 {dir} 创建成功"); + //CommitSave(); + } + else + { + UnityEngine.Debug.Log($"目录已存在,无需创建: {dir}"); + } + } + + //result = nn.fs.Directory.Create(fullDirectoryPath); + //if (!result.IsSuccess()) + //{ + // UnityEngine.Debug.LogError($"创建父目录失败: {result.GetErrorInfo()}"); + // return false; + //} + + //if (!CreateLoopDir(fullDirectoryPath)) + // return false; + + UnityEngine.Debug.Log($"父目录 {fullDirectoryPath} 创建成功"); + return true; + } + return false; + } + else if (result.IsSuccess() && entryType != nn.fs.EntryType.Directory) + { + // 路径存在,但不是目录 + UnityEngine.Debug.LogError($"路径 {fullDirectoryPath} 已存在,但不是目录"); + return false; + } + else if (!result.IsSuccess()) + { + // 其他错误 + UnityEngine.Debug.LogError($"检查父目录失败: {result.GetErrorInfo()}"); + return false; + } + // 路径存在且是目录 + UnityEngine.Debug.Log($"父目录 {fullDirectoryPath} 已存在且有效"); + return true; #endif - } - /// - /// 检查指定挂载点是否可访问 - /// - /// 路径前缀,例如 "save:/" 或 "sd:/" - /// 挂载点是否可访问 - bool IsMountPointAccessible(string pathPrefix) - { + } + /// + /// 检查指定挂载点是否可访问 + /// + /// 路径前缀,例如 "save:/" 或 "sd:/" + /// 挂载点是否可访问 + bool IsMountPointAccessible(string pathPrefix) + { #if !UNITY_SWITCH return false; #else - if (string.IsNullOrEmpty(pathPrefix)) - { - UnityEngine.Debug.LogError($"无效挂载点: {pathPrefix}"); - return false; - } + if (string.IsNullOrEmpty(pathPrefix)) + { + UnityEngine.Debug.LogError($"无效挂载点: {pathPrefix}"); + return false; + } - // 根据前缀判断挂载点类型并检查挂载状态 - if (pathPrefix == $"{save_name}:/") - { - if (!AxiNS.instance.mount.SaveIsMount) - { - UnityEngine.Debug.LogError($"{save_name}:/ 未挂载"); - return false; - } - return true; - } - else if (pathPrefix == "sd:/") - { - long freeSpace = 0; - // 检查 SD 卡挂载状态(示例,需根据实际实现调整) - nn.Result result = nn.fs.FileSystem.GetFreeSpaceSize(ref freeSpace, "sd:/"); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"sd:/ 未挂载或无法访问: {result.GetErrorInfo()}"); - return false; - } - return true; - } - else - { - UnityEngine.Debug.LogWarning($"未知挂载点 {pathPrefix},假定已挂载"); - return true; // 其他挂载点需根据实际需求实现 - } + // 根据前缀判断挂载点类型并检查挂载状态 + if (pathPrefix == $"{save_name}:/") + { + if (!AxiNS.instance.mount.SaveIsMount) + { + UnityEngine.Debug.LogError($"{save_name}:/ 未挂载"); + return false; + } + return true; + } + else if (pathPrefix == "sd:/") + { + long freeSpace = 0; + // 检查 SD 卡挂载状态(示例,需根据实际实现调整) + nn.Result result = nn.fs.FileSystem.GetFreeSpaceSize(ref freeSpace, "sd:/"); + if (!result.IsSuccess()) + { + UnityEngine.Debug.LogError($"sd:/ 未挂载或无法访问: {result.GetErrorInfo()}"); + return false; + } + return true; + } + else + { + UnityEngine.Debug.LogWarning($"未知挂载点 {pathPrefix},假定已挂载"); + return true; // 其他挂载点需根据实际需求实现 + } #endif - } + } }