namespace TTSDK
{
public class TTFileSystemManagerDefault : TTFileSystemManager
{
public static readonly TTFileSystemManagerDefault Instance = new TTFileSystemManagerDefault();
///
/// 将字符串写入文件(同步)
///
/// 要写入的文件路径
/// 要写入的文本
/// 指定写入文件的字符编码
/// 成功返回空字符串,失败返回错误信息
public override string WriteFileSync(string filePath, string data, string encoding = "utf8")
{
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(filePath)))
{
return $"{System.IO.Path.GetDirectoryName(filePath)} not exist";
}
try
{
System.IO.File.WriteAllText(filePath, data);
}
catch (System.Exception exception)
{
return exception.Message;
}
return "";
}
///
/// 将二进制写入文件(同步)
///
/// 要写入的文件路径
/// 要写入的二进制数据
/// 成功返回空字符串,失败返回错误信息
public override string WriteFileSync(string filePath, byte[] data)
{
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(filePath)))
{
return $"{System.IO.Path.GetDirectoryName(filePath)} not exist";
}
try
{
System.IO.File.WriteAllBytes(filePath, data);
}
catch (System.Exception exception)
{
return exception.Message;
}
return "";
}
///
/// 将二进制写入文件(异步)
///
///
public override void WriteFile(WriteFileParam param)
{
var errMsg = WriteFileSync(param.filePath, param.data);
CallbackBaseResponse(errMsg, param.success, param.fail);
}
///
/// 将字符串写入文件(异步)
///
///
public override void WriteFile(WriteFileStringParam param)
{
var errMsg = WriteFileSync(param.filePath, param.data);
CallbackBaseResponse(errMsg, param.success, param.fail);
}
///
/// 读取本地文件内容(异步)
///
///
public override void ReadFile(ReadFileParam param)
{
if (!System.IO.File.Exists(param.filePath))
{
CallbackReadFileResponse("file not exist", param.success, param.fail);
return;
}
if (string.IsNullOrEmpty(param.encoding) || param.encoding.Equals("binary"))
{
var data = System.IO.File.ReadAllBytes(param.filePath);
CallbackReadFileResponse("", param.success, param.fail, data);
}
else
{
var data = System.IO.File.ReadAllText(param.filePath);
CallbackReadFileResponse("", param.success, param.fail, null, data);
}
}
///
/// 从本地文件读取二进制数据数据(同步)
///
///
/// 字节数据,读取失败返回null
public override byte[] ReadFileSync(string filePath)
{
try
{
return System.IO.File.ReadAllBytes(filePath);
}
catch (System.Exception exception)
{
UnityEngine.Debug.LogError($"ReadFileSync: {exception.Message}");
return null;
}
}
///
/// 从本地文件读取字符串数据(同步)
///
/// 要读取的文件的路径
/// 指定读取文件的字符编码, 不能为空
/// 字符串数据,读取失败返回null
public override string ReadFileSync(string filePath, string encoding)
{
try
{
return System.IO.File.ReadAllText(filePath);
}
catch (System.Exception exception)
{
UnityEngine.Debug.LogError($"ReadFileSync: {exception.Message}");
return null;
}
}
///
/// 判断文件/目录是否存在(同步)
///
/// 要判断是否存在的文件/目录路径
/// 成功返回 true, 失败返回 false
public override bool AccessSync(string path)
{
return System.IO.File.Exists(path) || System.IO.Directory.Exists(path);
}
///
/// 判断文件/目录是否存在(异步)
///
///
public override void Access(AccessParam param)
{
var exist = AccessSync(param.path);
CallbackBaseResponse(exist ? "" : "no such file or directory", param.success, param.fail);
}
///
/// 复制文件(同步)
///
/// 源文件路径
/// 目标文件路径
/// 成功返回空字符串,失败返回错误信息
public override string CopyFileSync(string srcPath, string destPath)
{
if (System.IO.File.Exists(srcPath))
{
try
{
System.IO.File.Copy(srcPath, destPath, true);
}
catch (System.Exception exception)
{
return exception.Message;
}
return "";
}
else
{
return "source file not exist";
}
}
///
/// 复制文件(异步)
///
///
public override void CopyFile(CopyFileParam param)
{
var errMsg = CopyFileSync(param.srcPath, param.destPath);
CallbackBaseResponse(errMsg, param.success, param.fail);
}
///
/// 重命名文件(异步)
///
///
public override void RenameFile(RenameFileParam param)
{
var errMsg = RenameFileSync(param.srcPath, param.destPath);
CallbackBaseResponse(errMsg, param.success, param.fail);
}
///
/// 重命名文件(同步)
///
/// 源文件路径
/// 目标文件路径
/// 成功返回空字符串,失败返回错误信息
public override string RenameFileSync(string srcPath, string destPath)
{
if (System.IO.File.Exists(srcPath))
{
try
{
if (System.IO.File.Exists(destPath))
{
System.IO.File.Delete(destPath);
}
System.IO.File.Move(srcPath, destPath);
}
catch (System.Exception exception)
{
return exception.Message;
}
return "";
}
return "source file not exist";
}
///
/// 删除文件(同步)
///
/// 源文件路径,支持本地路径
/// 成功返回空字符串,失败返回错误信息
public override string UnlinkSync(string filePath)
{
if (System.IO.File.Exists(filePath))
{
try
{
System.IO.File.Delete(filePath);
}
catch (System.Exception exception)
{
return exception.Message;
}
return "";
}
return "file not exist";
}
///
/// 删除文件(异步)
///
///
public override void Unlink(UnlinkParam param)
{
var errMsg = UnlinkSync(param.filePath);
CallbackBaseResponse(errMsg, param.success, param.fail);
}
///
/// 创建目录(异步)
///
///
public override void Mkdir(MkdirParam param)
{
var errMsg = MkdirSync(param.dirPath, param.recursive);
CallbackBaseResponse(errMsg, param.success, param.fail);
}
///
/// 创建目录(同步)
///
/// 创建的目录路径
/// 是否在递归创建该目录的上级目录后再创建该目录。如果对应的上级目录已经存在,则不创建该上级目录。如 dirPath 为 a/b/c/d 且 recursive 为 true,将创建 a 目录,再在 a 目录下创建 b 目录,以此类推直至创建 a/b/c 目录下的 d 目录。
/// 成功返回空字符串,失败返回错误信息
public override string MkdirSync(string dirPath, bool recursive = false)
{
if (!System.IO.Directory.Exists(dirPath))
{
try
{
System.IO.Directory.CreateDirectory(dirPath);
}
catch (System.Exception exception)
{
return exception.Message;
}
}
return "";
}
///
/// 删除目录(异步)
///
///
public override void Rmdir(RmdirParam param)
{
var errMsg = RmdirSync(param.dirPath, param.recursive);
CallbackBaseResponse(errMsg, param.success, param.fail);
}
///
/// 删除目录(同步)
///
/// 创建的目录路径
/// 是否递归删除目录。如果为 true,则删除该目录和该目录下的所有子目录以及文件 。
/// 成功返回空字符串,失败返回错误信息
public override string RmdirSync(string dirPath, bool recursive = false)
{
if (System.IO.Directory.Exists(dirPath))
{
try
{
System.IO.Directory.Delete(dirPath, recursive);
}
catch (System.Exception exception)
{
return exception.Message;
}
return "";
}
else
{
return "directory not exist";
}
}
///
/// 读取文件描述信息(同步)
///
/// 文件/目录路径
/// 是否递归获取目录下的每个文件的 Stat 信息
/// 是否抛出错误信息,如果抛出错误信息,当文件不存在时则会抛出异常,错误信息从异常中获取。
/// 返回文件信息,如果访问失败则返回null
public override TTStatInfo StatSync(string path, bool throwException = false)
{
if (System.IO.File.Exists(path))
{
var fileInfo = new System.IO.FileInfo(path);
return new TTStatInfo()
{
size = fileInfo.Length,
mode = 33060,
lastAccessedTime = GetUnixTime(fileInfo.LastAccessTime.Ticks),
lastModifiedTime = GetUnixTime(fileInfo.LastWriteTime.Ticks)
};
}
else if (System.IO.Directory.Exists(path))
{
var dirInfo = new System.IO.DirectoryInfo(path);
return new TTStatInfo()
{
size = 0,
mode = 16676,
lastAccessedTime = GetUnixTime(dirInfo.LastAccessTime.Ticks),
lastModifiedTime = GetUnixTime(dirInfo.LastWriteTime.Ticks)
};
}
else
{
return null;
}
}
///
/// 读取文件描述信息(异步)
///
///
public override void Stat(StatParam param)
{
var info = StatSync(param.path);
if (info != null)
{
param.success?.Invoke(new TTStatResponse()
{
stat = info
});
}
else
{
param.fail?.Invoke(new TTStatResponse()
{
errCode = -1,
errMsg = "No such file or directory"
});
}
}
private void GetFilesRecursively(string path, System.Collections.Generic.List fileInfos)
{
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(path);
if (dir.Exists)
{
System.IO.FileInfo[] files = dir.GetFiles();
if (files != null && files.Length > 0)
{
System.DateTime unixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
foreach (System.IO.FileInfo file in files)
{
long unixTimeStampInTicks = (file.CreationTime.ToUniversalTime() - unixEpoch).Ticks;
long unixTimeStampInSeconds = unixTimeStampInTicks / System.TimeSpan.TicksPerSecond;
fileInfos.Add(new TTFileInfo()
{
mode = 33060,
size = file.Length,
createTime = unixTimeStampInSeconds,
filePath = file.FullName
});
}
}
System.IO.DirectoryInfo[] subDirs = dir.GetDirectories();
if (subDirs != null && subDirs.Length > 0)
{
System.DateTime unixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
foreach (var subDir in subDirs)
{
long unixTimeStampInTicks = (subDir.CreationTime.ToUniversalTime() - unixEpoch).Ticks;
long unixTimeStampInSeconds = unixTimeStampInTicks / System.TimeSpan.TicksPerSecond;
fileInfos.Add(new TTFileInfo()
{
mode = 16676,
size = 0,
createTime = unixTimeStampInSeconds,
filePath = subDir.FullName
});
GetFilesRecursively(subDir.FullName, fileInfos);
}
}
}
}
///
/// 获取保存的用户目录文件列表
///
public override void GetSavedFileList(GetSavedFileListParam param)
{
System.Collections.Generic.List fileInfos =
new System.Collections.Generic.List();
GetFilesRecursively(UnityEngine.Application.persistentDataPath, fileInfos);
param.success?.Invoke(new TTGetSavedFileListResponse()
{
fileList = fileInfos.ToArray()
});
}
///
/// 根据url链接获取本地缓存文件路径
///
/// 输入文件下载链接url
/// 返回本地缓存文件路径,以scfile://user开头的路径,可以直接用这个路径访问该文件
public override string GetLocalCachedPathForUrl(string url)
{
return "";
}
///
/// 判断该url是否有本地缓存文件
///
/// 输入文件下载链接url
/// 如果存在缓存文件则返回true,不存在缓存文件则返回false
public override bool IsUrlCached(string url)
{
return false;
}
private static void CallbackReadFileResponse(string errMsg,
System.Action success,
System.Action fail,
byte[] binData = null,
string stringData = null)
{
if (string.IsNullOrEmpty(errMsg))
{
success?.Invoke(new TTReadFileResponse()
{
binData = binData,
stringData = stringData
});
}
else
{
fail?.Invoke(new TTReadFileResponse()
{
errCode = -1,
errMsg = errMsg
});
}
}
private static void CallbackBaseResponse(string errMsg, System.Action success,
System.Action fail)
{
if (string.IsNullOrEmpty(errMsg))
{
success?.Invoke(new TTBaseResponse());
}
else
{
fail?.Invoke(new TTBaseResponse()
{
errCode = -1,
errMsg = errMsg
});
}
}
private static long GetUnixTime(long ticks)
{
var epochTicks = new System.DateTime(1970, 1, 1).Ticks;
var unixTime = ((ticks - epochTicks) / System.TimeSpan.TicksPerSecond);
return unixTime;
}
}
}