make file writer API pseudo-async

This commit is contained in:
alexiscatnip
2022-08-06 02:43:06 +08:00
committed by alexiscatnip
parent 9f23fb3aae
commit b47a71e40b
3 changed files with 77 additions and 45 deletions
@@ -29,7 +29,7 @@ namespace Raindrop.Services.Bootstrap
SceneManager.LoadScene("Raindrop/Bootstrap/MainScene");
}
//perform check-copy operation.
// prep user file system for LMV's usage, by copying static files.
private static void CheckAndUpdate_StaticFileSystem()
{
var copier = StaticFilesCopier.GetInstance();
@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Threading.Tasks;
using OpenMetaverse;
using UnityEngine;
@@ -87,6 +88,32 @@ namespace Disk
Debug.Log($"write: {filePath} ");
}
//easily write to a file
//filePath = fully-specified file path
public static async Task WriteToFileAsync(byte[] outbytes, string filePath)
{
//create parent subfolders
var parentDir = Path.GetDirectoryName(filePath);
System.IO.Directory.CreateDirectory(parentDir);
await Task.Run(() =>
{
//write file
try
{
System.IO.File.WriteAllBytes(filePath, outbytes);
}
catch (IOException e)
{
OpenMetaverse.Logger.Log(
"error writing bytes to filepath : " + filePath + " " +
e.ToString(), Helpers.LogLevel.Error);
}
});
Debug.Log($"write: {filePath} ");
}
//easily write to a file
//filePath = fully-specified file path
public static void WriteToFile(string toWrite, string filePath)
+49 -44
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Disk;
using OpenMetaverse;
using SearchOption = System.IO.SearchOption;
@@ -41,10 +42,11 @@ namespace UnityScripts.Disk
//returns -1 if failed.
private int CheckOmvDataFolderAndUpdateItIfNecessary()
{
List<string> updatedFiles = null;
Task<List<string>> updatedFilesTask = null;
try
{
updatedFiles = CopyIfRequired_StreamingAssetsFolder(
updatedFilesTask = Copy_StreamingAssetsFolder_To_UserDataRoot_Async(
DirectoryHelpers.GetInternalStorageDir()
);
}
@@ -52,8 +54,9 @@ namespace UnityScripts.Disk
{
return -1;
}
if (updatedFiles.Count > 0)
var updatedFiles = updatedFilesTask.Result; //blocking call.
if (updatedFiles.Count > 0)
{
var printString = String.Join(Environment.NewLine, updatedFiles);
OpenMetaverse.Logger.Log(
@@ -63,21 +66,16 @@ namespace UnityScripts.Disk
Helpers.LogLevel.Info
);
}
else
{
OpenMetaverse.Logger.Log(
"staticAssets are already latest version in : "
+ DirectoryHelpers.GetInternalStorageDir(),
Helpers.LogLevel.Info
);
}
return 0;
}
// scan all files in streamingAssets folder, and copy any changed/missing files into userDataRoot.
// return some files that were updated.
private List<string> CopyIfRequired_StreamingAssetsFolder(string appRootPath)
// scan all files in streamingAssets folder,
// and copy any changed/missing files into userDataRoot.
// return the list of files that were updated.
private async Task<List<string>>
Copy_StreamingAssetsFolder_To_UserDataRoot_Async(
string appRootPath)
{
List<String> updatedFiles = new List<string>();
@@ -88,49 +86,39 @@ namespace UnityScripts.Disk
throw new Exception(
"StreamingAssets root not accessible.");
}
string[] paths =
BetterStreamingAssets.GetFiles(
slash,
"*",
SearchOption.AllDirectories);
string[] fromPaths = BetterStreamingAssets.GetFiles(
slash,
"*",
SearchOption.AllDirectories);
if (paths.Length == 0)
if (fromPaths.Length == 0)
{
throw new Exception(
"StreamingAssets has no files in it.");
}
foreach (var sourcePath in paths)
{
string relativePath = "";
//find the equivalent path in appRootPath
string root = Directory.GetDirectoryRoot(sourcePath);
if (root != null/*todo: check for failed get root.*/)
{
// gotta remove that root slash character '\'
relativePath = sourcePath.Substring(root.Length - 1);
}
//1. check for missing file
foreach (var fromPath in fromPaths)
{
var relativePath = RemoveRootFolderFromPath(fromPath);
string targetPath = Path.Combine(appRootPath, relativePath);
if (!File.Exists(targetPath))
//1. check for missing file
bool fileIsMissing = !File.Exists(targetPath);
if (fileIsMissing)
{
updatedFiles.Add(targetPath);
DirectoryHelpers.WriteToFile(
BetterStreamingAssets.ReadAllBytes(sourcePath),
DirectoryHelpers.WriteToFileAsync(
BetterStreamingAssets.ReadAllBytes(fromPath),
targetPath);
continue;
}
//2. check for diffs in the file.
bool fileIsDifferent = false;
using (Stream fs1 = File.OpenRead(targetPath))
using (Stream fs2 = BetterStreamingAssets.OpenRead(sourcePath))
using (Stream fs2 = BetterStreamingAssets.OpenRead(fromPath))
{
if (FileHelpers.FileStreamsAreEqual(fs1, fs2))
{
//do nothing
}
else
if (!FileHelpers.FileStreamsAreEqual(fs1, fs2))
{
fileIsDifferent = true;
}
@@ -138,12 +126,29 @@ namespace UnityScripts.Disk
if (fileIsDifferent)
{
updatedFiles.Add(targetPath);
DirectoryHelpers.WriteToFile(
BetterStreamingAssets.ReadAllBytes(sourcePath),
DirectoryHelpers.WriteToFileAsync(
BetterStreamingAssets.ReadAllBytes(fromPath),
targetPath);
}
}
return updatedFiles;
// remove root folder:
// ie: /streamingAssets/a/b/ -> /a/b/
string RemoveRootFolderFromPath(string fullPath)
{
string relativePath = "";
//find the equivalent path in appRootPath
string fromPath_Root = Directory.GetDirectoryRoot(fullPath);
if (fromPath_Root != null /*todo: check for failed get root.*/)
{
// gotta remove that root slash character '\'
relativePath = fullPath.Substring(fromPath_Root.Length - 1);
}
return relativePath;
}
}
}
}