private void DumpReadAllLines(bool isLocal) { Console.WriteLine("\n=== TEST {0} ===", isLocal ? UnitTestConstants.Local : UnitTestConstants.Network); var tmp = Path.Combine(Path.GetTempPath(), "File.SetAttributes()-" + Path.GetRandomFileName()); var tempPath = isLocal ? tmp : Path.LocalToUnc(tmp); // Create file and append text. var tempFile = Path.GetTempFileName(); string[] createText = { "Hello", "And", "Welcome" }; File.WriteAllLines(tempFile, createText); Console.WriteLine("\nFile.ReadAllLines()\n"); var readText = File.ReadAllLines(tempFile); foreach (var s in readText) { Console.WriteLine("\t{0}", s); Assert.IsTrue(createText.Contains(s)); } Console.WriteLine("\nFile.ReadLines()\n"); foreach (var s in File.ReadLines((tempFile))) { Console.WriteLine("\t{0}", s); Assert.IsTrue(createText.Contains(s)); } File.Delete(tempFile, true); Assert.IsFalse(File.Exists(tempFile), "Cleanup failed: File should have been removed."); }
public async Task <AbstractDownloadState> GetDownloaderState(dynamic archiveINI) { var gameName = (string)archiveINI?.General?.gameName; var gameFile = (string)archiveINI?.General?.gameFile; if (gameFile == null || gameFile == null) { return(null); } var game = GameRegistry.GetByMO2ArchiveName(gameName); if (game == null) { return(null); } var path = game.GameLocation(); var filePath = Path.Combine(path, gameFile); if (!File.Exists(filePath)) { return(null); } var hash = filePath.FileHashCached(); return(new State { Game = GameRegistry.GetByMO2ArchiveName(gameName).Game, GameFile = gameFile, Hash = hash, }); }
/// <summary> /// Remove any orphaned files in the DB. /// </summary> private void CleanDB() { Utils.Log("Cleaning VFS cache"); lock (this) { _files.Values .Where(f => { if (f.IsConcrete) { return(!File.Exists(f.StagedPath)); } if (f.Hash == null) { return(true); } while (f.ParentPath != null) { if (Lookup(f.ParentPath) == null) { return(true); } if (f.Hash == null) { return(true); } f = Lookup(f.ParentPath); } return(false); }) .ToList() .Do(f => _files.Remove(f.FullPath)); } }
private void DumpClassByHandleFileInfo(bool isLocal) { Console.WriteLine("\n=== TEST {0} ===", isLocal ? UnitTestConstants.Local : UnitTestConstants.Network); var tempPath = Path.GetTempPath("File.GetFileInfoByHandle()-" + Path.GetRandomFileName()); if (!isLocal) { tempPath = Path.LocalToUnc(tempPath); } Console.WriteLine("\nInput File Path: [{0}]", tempPath); var stream = File.Create(tempPath); stream.WriteByte(1); UnitTestConstants.StopWatcher(true); var bhfi = File.GetFileInfoByHandle(stream.SafeFileHandle); Console.WriteLine(UnitTestConstants.Reporter()); Assert.IsTrue(UnitTestConstants.Dump(bhfi, -18)); Assert.AreEqual(System.IO.File.GetCreationTimeUtc(tempPath), bhfi.CreationTimeUtc); Assert.AreEqual(System.IO.File.GetLastAccessTimeUtc(tempPath), bhfi.LastAccessTimeUtc); Assert.AreEqual(System.IO.File.GetLastWriteTimeUtc(tempPath), bhfi.LastWriteTimeUtc); stream.Close(); File.Delete(tempPath, true); Assert.IsFalse(File.Exists(tempPath), "Cleanup failed: File should have been removed."); Console.WriteLine(); }
public void File_WriteAllLines() { Console.WriteLine("File.WriteAllLines()"); Console.WriteLine("\n Default AlphaFS Encoding: [{0}]", NativeMethods.DefaultFileEncoding.EncodingName); // Create file and append text. var tempFile = Path.GetTempFileName(); var allLines = new[] { UnitTestConstants.TenNumbers, UnitTestConstants.TextHelloWorld, UnitTestConstants.TextGoodbyeWorld, UnitTestConstants.TextUnicode }; // Create real UTF-8 file. File.WriteAllLines(tempFile, allLines, NativeMethods.DefaultFileEncoding); // Read filestream contents. using (var streamRead = File.OpenText(tempFile)) { var line = streamRead.ReadToEnd(); Console.WriteLine("\n Created: [{0}] filestream: [{1}]\n\n WriteAllLines content:\n{2}", streamRead.CurrentEncoding.EncodingName, tempFile, line); foreach (var line2 in allLines) { Assert.IsTrue(line.Contains(line2)); } } File.Delete(tempFile, true); Assert.IsFalse(File.Exists(tempFile), "Cleanup failed: File should have been removed."); }
private async Task InstallIncludedFiles() { Info("Writing inline files"); await ModList.Directives .OfType <InlineFile>() .PMap(Queue, directive => { Status($"Writing included file {directive.To}"); var outPath = Path.Combine(OutputFolder, directive.To); if (File.Exists(outPath)) { File.Delete(outPath); } if (directive is RemappedInlineFile) { WriteRemappedFile((RemappedInlineFile)directive); } else if (directive is CleanedESM) { GenerateCleanedESM((CleanedESM)directive); } else { File.WriteAllBytes(outPath, LoadBytesFromPath(directive.SourceDataID)); } }); }
private void GenerateCleanedESM(CleanedESM directive) { var filename = Path.GetFileName(directive.To); var gameFile = Path.Combine(GameFolder, "Data", filename); Info($"Generating cleaned ESM for {filename}"); if (!File.Exists(gameFile)) { throw new InvalidDataException($"Missing {filename} at {gameFile}"); } Status($"Hashing game version of {filename}"); var sha = gameFile.FileHash(); if (sha != directive.SourceESMHash) { throw new InvalidDataException( $"Cannot patch {filename} from the game folder because the hashes do not match. Have you already cleaned the file?"); } var patchData = LoadBytesFromPath(directive.SourceDataID); var toFile = Path.Combine(OutputFolder, directive.To); Status($"Patching {filename}"); using (var output = File.Open(toFile, FileMode.Create)) using (var input = File.OpenRead(gameFile)) { BSDiff.Apply(input, () => new MemoryStream(patchData), output); } }
private static void SetupNLog() { if (File.Exists("Nlog.config")) { return; } var config = new LoggingConfiguration(); var loglevel = LogLevel.Info; var layout = @"${message}"; var consoleTarget = new ColoredConsoleTarget(); var whr = new ConsoleWordHighlightingRule("this will be replaced with search term", ConsoleOutputColor.Red, ConsoleOutputColor.Green); consoleTarget.WordHighlightingRules.Add(whr); config.AddTarget("console", consoleTarget); consoleTarget.Layout = layout; var rule1 = new LoggingRule("*", loglevel, consoleTarget); config.LoggingRules.Add(rule1); LogManager.Configuration = config; }
public static bool TryGetHashCache(string file, out string hash) { var hashFile = file + Consts.HashFileExtension; hash = null; if (!File.Exists(hashFile)) { return(false); } if (File.GetSize(hashFile) != 20) { return(false); } using var fs = File.OpenRead(hashFile); using var br = new BinaryReader(fs); var version = br.ReadUInt32(); if (version != HashCacheVersion) { return(false); } var lastModified = br.ReadUInt64(); if (lastModified != File.GetLastWriteTimeUtc(file).AsUnixTime()) { return(false); } hash = BitConverter.GetBytes(br.ReadUInt64()).ToBase64(); return(true); }
private void DumpReadWriteAllBytes(bool isLocal) { Console.WriteLine("\n=== TEST {0} ===", isLocal ? UnitTestConstants.Local : UnitTestConstants.Network); var tempPath = Path.GetTempPath("File.ReadWriteAllBytes()-" + Path.GetRandomFileName()); if (!isLocal) { tempPath = Path.LocalToUnc(tempPath); } var size = 10000; var text = Encoding.UTF8.GetBytes(new string('X', size)); var allOk = true; try { File.WriteAllBytes(tempPath, text); Console.WriteLine("\nWriteAllBytes(): [{0}] bytes: [{1}]", size, tempPath); } catch (Exception ex) { allOk = false; Console.WriteLine("\n\tCaught (unexpected) {0}: [{1}]", ex.GetType().FullName, ex.Message.Replace(Environment.NewLine, " ")); } Assert.IsTrue(File.Exists(tempPath), "File.WriteAllBytes(): File was not created."); var fileSize = File.GetSize(tempPath); Assert.AreEqual(size, fileSize); Assert.IsTrue(allOk); byte[] readAllAlphaFS = { }; byte[] readAllSysIo = { }; try { readAllAlphaFS = File.ReadAllBytes(tempPath); readAllSysIo = System.IO.File.ReadAllBytes(tempPath); Console.WriteLine("\nReadAllBytes(): [{0}] bytes.", readAllAlphaFS.Length); } catch (Exception ex) { allOk = false; Console.WriteLine("\n\tCaught (unexpected) {0}: [{1}]", ex.GetType().FullName, ex.Message.Replace(Environment.NewLine, " ")); } Assert.AreEqual(readAllAlphaFS.Length, fileSize, "File.ReadAllBytes(): Number of bytes are different."); Assert.AreEqual(readAllAlphaFS.Length, readAllSysIo.Length, "File.ReadAllBytes(): AlphaFS != System.IO"); File.Delete(tempPath, true); Assert.IsFalse(File.Exists(tempPath), "Cleanup failed: File should have been removed."); Assert.IsTrue(allOk); Console.WriteLine("\n"); }
public async Task <IActionResult> DeleteUpdates() { var lists = await SQL.GetDetailedModlistStatuses(); var archives = lists.SelectMany(list => list.Archives) .Select(a => a.Archive.Hash.ToHex()) .ToHashSet(); var toDelete = new List <string>(); var toSave = new List <string>(); using (var client = new FtpClient("storage.bunnycdn.com")) { client.Credentials = new NetworkCredential(_settings.BunnyCDN_User, _settings.BunnyCDN_Password); await client.ConnectAsync(); foreach (var file in Directory.GetFiles("updates")) { var relativeName = Path.GetFileName(file); var parts = Path.GetFileName(file).Split('_', StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 2) { continue; } if (parts[0] == parts[1]) { toDelete.Add(relativeName); continue; } if (!archives.Contains(parts[0])) { toDelete.Add(relativeName); } else { toSave.Add(relativeName); } } foreach (var delete in toDelete) { Utils.Log($"Deleting update {delete}"); if (await client.FileExistsAsync($"updates/{delete}")) { await client.DeleteFileAsync($"updates/{delete}"); } if (AlphaFile.Exists($"updates\\{delete}")) { AlphaFile.Delete($"updates\\{delete}"); } } } return(Ok(new { Save = toSave.ToArray(), Delete = toDelete.ToArray() }.ToJson())); }
// 解析视频标注文件 private List <VideoInfo> ParseXml(string xmlFile) { if (File.Exists(xmlFile)) { List <VideoInfo> videos = new List <VideoInfo>(); XmlDocument doc = new XmlDocument(); XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreComments = true; // 忽略文档里面的注释 XmlReader reader = XmlReader.Create(xmlFile, settings); doc.Load(reader); XmlNode xn = doc.SelectSingleNode("root"); // 根节点 XmlNodeList xnl = xn.ChildNodes; // 根节点的子节点 foreach (XmlNode node in xnl) { string _video = node.Attributes["name"].Value; string _scene = node.Attributes["scene"].Value; XmlNodeList subNodes = node.ChildNodes; if (subNodes.Count > 0) { foreach (XmlNode item in subNodes) { string _incident = item.Name; int _count = item.InnerText.ToInt().Value; var _videoInfoItem = new VideoInfo { Scene = _scene, VideoName = _video, Incident = _incident, Count = _count }; videos.Add(_videoInfoItem); } } else // 无事件发生 { var _videoInfoItem = new VideoInfo { Scene = _scene, VideoName = _video, Incident = "null", Count = 0 }; videos.Add(_videoInfoItem); } } reader.Close(); return(videos); } else { MessageWindow.ShowDialog($"无法访问文件 [{xmlFile}]"); } return(null); }
/// <summary> /// The user may already have some files in the OutputFolder. If so we can go through these and /// figure out which need to be updated, deleted, or left alone /// </summary> public async Task OptimizeModlist() { Utils.Log("Optimizing Modlist directives"); var indexed = ModList.Directives.ToDictionary(d => d.To); UpdateTracker.NextStep("Looking for files to delete"); await Directory.EnumerateFiles(OutputFolder, "*", DirectoryEnumerationOptions.Recursive) .PMap(Queue, UpdateTracker, f => { var relative_to = f.RelativeTo(OutputFolder); Utils.Status($"Checking if modlist file {relative_to}"); if (indexed.ContainsKey(relative_to) || f.IsInPath(DownloadFolder)) { return; } Utils.Log($"Deleting {relative_to} it's not part of this modlist"); File.Delete(f); }); UpdateTracker.NextStep("Looking for unmodified files"); (await indexed.Values.PMap(Queue, UpdateTracker, d => { // Bit backwards, but we want to return null for // all files we *want* installed. We return the files // to remove from the install list. Status($"Optimizing {d.To}"); var path = Path.Combine(OutputFolder, d.To); if (!File.Exists(path)) { return(null); } var fi = new FileInfo(path); if (fi.Length != d.Size) { return(null); } return(path.FileHash() == d.Hash ? d : null); })) .Where(d => d != null) .Do(d => indexed.Remove(d.To)); UpdateTracker.NextStep("Updating Modlist"); Utils.Log($"Optimized {ModList.Directives.Count} directives to {indexed.Count} required"); var requiredArchives = indexed.Values.OfType <FromArchive>() .GroupBy(d => d.ArchiveHashPath[0]) .Select(d => d.Key) .ToHashSet(); ModList.Archives = ModList.Archives.Where(a => requiredArchives.Contains(a.Hash)).ToList(); ModList.Directives = indexed.Values.ToList(); }
public static void ToJSON <T>(this T obj, string filename) { if (File.Exists(filename)) { File.Delete(filename); } File.WriteAllText(filename, JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto })); }
public static IErrorResponse CheckValidInstallPath(string path) { var ret = Utils.IsDirectoryPathValid(path); if (!ret.Succeeded) { return(ret); } if (!Directory.Exists(path)) { return(ErrorResponse.Success); } // Check folder does not have a wabbajack modlist foreach (var file in Directory.EnumerateFiles(path, DirectoryEnumerationOptions.Recursive)) { if (!File.Exists(file)) { continue; } if (System.IO.Path.GetExtension(file).Equals(ExtensionManager.Extension)) { return(ErrorResponse.Fail($"Cannot install into a folder with a wabbajack modlist inside of it.")); } } // Check folder is either empty, or a likely valid previous install if (!Directory.IsEmpty(path)) { // Some probably naive check, but should be a good starting point to improve later if (!Directory.EnumerateFiles(path).Any(file => { var fileName = Path.GetFileName(file); if (fileName.Equals("ModOrganizer.exe", StringComparison.OrdinalIgnoreCase)) { return(true); } if (fileName.Equals("ModOrganizer.ini", StringComparison.OrdinalIgnoreCase)) { return(true); } return(false); })) { return(ErrorResponse.Fail($"Cannot install into a non-empty folder that does not look like a previous WJ installation.")); } } return(ErrorResponse.Success); }
public static string FileHashCached(this string file, bool nullOnIOError = false) { var hashPath = file + Consts.HashFileExtension; if (File.Exists(hashPath) && File.GetLastWriteTime(file) <= File.GetLastWriteTime(hashPath)) { return(File.ReadAllText(hashPath)); } var hash = file.FileHash(nullOnIOError); File.WriteAllText(hashPath, hash); return(hash); }
public static EntryStore Read(string file) { if (File.Exists(file)) { using (var fs = File.Open(file, FileMode.Open)) { var entryStore = Read(fs); entryStore.SetInMemoryFields(); entryStore.SetSummaryFields(); return(entryStore); } } return(null); }
private async Task InstallIncludedDownloadMetas() { await ModList.Directives .OfType <ArchiveMeta>() .PMap(Queue, directive => { Status($"Writing included .meta file {directive.To}"); var outPath = Path.Combine(DownloadFolder, directive.To); if (File.Exists(outPath)) { File.Delete(outPath); } File.WriteAllBytes(outPath, LoadBytesFromPath(directive.SourceDataID)); }); }
public override async ValueTask <Directive> Run(RawSourceFile source) { if (!_mergesIndexed.TryGetValue(source.AbsolutePath, out var merge)) { return(null); } var result = source.EvolveTo <MergedPatch>(); result.Sources = merge.plugins.Select(f => { var orig_path = Path.Combine(f.dataFolder, f.filename); var paths = new[] { orig_path, orig_path + ".mohidden", Path.Combine(Path.GetDirectoryName(orig_path), "optional", Path.GetFileName(orig_path)) }; var abs_path = paths.FirstOrDefault(p => File.Exists(p)); if (abs_path == null) { throw new InvalidDataException( $"File {abs_path} is required to build {merge.filename} but it doesn't exist searched in: \n" + String.Join("\n", paths)); } return(new SourcePatch { RelativePath = abs_path.RelativeTo(_mo2Compiler.MO2Folder), Hash = _compiler.VFS.Index.ByFullPath[abs_path].Hash }); }).ToList(); var src_data = result.Sources.Select(f => File.ReadAllBytes(Path.Combine(_mo2Compiler.MO2Folder, f.RelativePath))) .ConcatArrays(); var dst_data = File.ReadAllBytes(source.AbsolutePath); await using (var ms = new MemoryStream()) { await Utils.CreatePatch(src_data, dst_data, ms); result.PatchID = _compiler.IncludeFile(ms.ToArray()); } return(result); }
public void VerifyAllFiles() { var skip_files = new HashSet <string> { "portable.txt" }; foreach (var dest_file in Directory.EnumerateFiles(InstallFolder, "*", DirectoryEnumerationOptions.Recursive)) { var rel_file = dest_file.RelativeTo(InstallFolder); if (rel_file.StartsWith(Consts.LOOTFolderFilesDir) || rel_file.StartsWith(Consts.GameFolderFilesDir)) { continue; } if (!skip_files.Contains(rel_file)) { Assert.IsTrue(File.Exists(Path.Combine(MO2Folder, rel_file)), $"Only in Destination: {rel_file}"); } } var skip_extensions = new HashSet <string> { ".txt", ".ini" }; foreach (var src_file in Directory.EnumerateFiles(MO2Folder, "*", DirectoryEnumerationOptions.Recursive)) { var rel_file = src_file.RelativeTo(MO2Folder); if (rel_file.StartsWith("downloads\\")) { continue; } var dest_file = Path.Combine(InstallFolder, rel_file); Assert.IsTrue(File.Exists(dest_file), $"Only in Source: {rel_file}"); var fi_src = new FileInfo(src_file); var fi_dest = new FileInfo(dest_file); if (!skip_extensions.Contains(Path.GetExtension(src_file))) { Assert.AreEqual(fi_src.Length, fi_dest.Length, $"Differing sizes {rel_file}"); Assert.AreEqual(src_file.FileHash(), dest_file.FileHash(), $"Differing content hash {rel_file}"); } } }
public async ValueTask DisposeAsync() { var exts = new[] { ".md", ".exe" }; await WorkingDirectory.Combine(ID).DeleteDirectory(); Profiles.Do(p => { foreach (var ext in exts) { var path = Path.Combine(Directory.GetCurrentDirectory(), p + ext); if (File.Exists(path)) { File.Delete(path); } } }); }
public void Dispose() { var exts = new [] { ".md", ".exe" }; Utils.DeleteDirectory(Path.Combine(WorkingDirectory, ID)); Profiles.Do(p => { foreach (var ext in exts) { var path = Path.Combine(Directory.GetCurrentDirectory(), p + ext); if (File.Exists(path)) { File.Delete(path); } } }); }
private void ForcePortable() { var path = Path.Combine(OutputFolder, "portable.txt"); if (File.Exists(path)) { return; } try { File.WriteAllText(path, "Created by Wabbajack"); } catch (Exception e) { Utils.Error(e, $"Could not create portable.txt in {OutputFolder}"); } }
public void File_ReadAllText() { Console.WriteLine("File.ReadAllText()\n"); // Create file and append text. var tempFile = Path.GetTempFileName(); string[] createText = { "Hello", "And", "Welcome" }; File.WriteAllLines(tempFile, createText); // Open the file to read from. var textRead = File.ReadAllText(tempFile); Console.WriteLine(textRead); File.Delete(tempFile, true); Assert.IsFalse(File.Exists(tempFile), "Cleanup failed: File should have been removed."); }
public void File_WriteAllText() { Console.WriteLine("File.WriteAllText()"); Console.WriteLine("\n\tDefault AlphaFS Encoding: [{0}]", NativeMethods.DefaultFileEncoding.EncodingName); // Create file and append text. var tempFile = Path.GetTempFileName(); var allLines = UnitTestConstants.TextHelloWorld; // Create real UTF-8 file. File.WriteAllText(tempFile, allLines, NativeMethods.DefaultFileEncoding); // Read filestream contents. using (var streamRead = File.OpenText(tempFile)) { var line = streamRead.ReadToEnd(); Console.WriteLine("\n\tCreated: [{0}] filestream: [{1}]\n\n\tWriteAllText content:\n{2}", streamRead.CurrentEncoding.EncodingName, tempFile, line); Assert.IsTrue(line.Contains(allLines)); } // (over)Write. File.WriteAllText(tempFile, "Append 1"); File.WriteAllText(tempFile, allLines); File.WriteAllText(tempFile, "Append 2"); File.WriteAllText(tempFile, allLines); // Read filestream contents. using (var streamRead = File.OpenText(tempFile)) { var line = streamRead.ReadToEnd(); Console.WriteLine("\tWriteAllText content:\n{0}", line); Assert.IsTrue(line.Contains(allLines)); Assert.IsTrue(!line.Contains("Append 1")); Assert.IsTrue(!line.Contains("Append 2")); } File.Delete(tempFile, true); Assert.IsFalse(File.Exists(tempFile), "Cleanup failed: File should have been removed."); }
public static void Rotate(string filenameBase) { if (File.Exists(filenameBase)) { for (int i = 8; i >= 0; i--) { string fn = filenameBase + "." + i; if (File.Exists(fn)) { string fn2 = filenameBase + "." + (i + 1); if (File.Exists(fn2)) { File.Delete(fn2); } File.Move(fn, fn2); } } File.Copy(filenameBase, filenameBase + ".0"); } }
public void SyncToDisk() { if (!_disableDiskCache) { Utils.Status("Syncing VFS Cache"); lock (this) { try { _isSyncing = true; if (File.Exists("vfs_cache.bin_new")) { File.Delete("vfs_cache.bin_new"); } using (var fs = File.OpenWrite("vfs_cache.bin_new")) using (var bw = new BinaryWriter(fs)) { Utils.Log($"Syncing VFS to Disk: {_files.Count} entries"); foreach (var f in _files.Values) { f.Write(bw); } } if (File.Exists("vfs_cache.bin")) { File.Delete("vfs_cache.bin"); } File.Move("vfs_cache.bin_new", "vfs_cache.bin"); } finally { _isSyncing = false; } } } }
// 导出数据 private void ExportData(object sender, RoutedEventArgs e) { if (!File.Exists("./data.db")) { MessageWindow.ShowDialog("文件 data.db 不存在", this); return; } SaveFileDialog dlg = new SaveFileDialog { Title = "另存为", FileName = "data.db", DefaultExt = ".db", Filter = "Data base file|*.db" }; if (dlg.ShowDialog() == true) { FileInfo fi = new FileInfo("./data.db"); fi.CopyTo(dlg.FileName); } }
private static void SetupNLog() { if (File.Exists(Path.Combine(BaseDirectory, "Nlog.config"))) { return; } var config = new LoggingConfiguration(); var loglevel = LogLevel.Info; var layout = @"${message}"; var consoleTarget = new ColoredConsoleTarget(); config.AddTarget("console", consoleTarget); consoleTarget.Layout = layout; var rule1 = new LoggingRule("*", loglevel, consoleTarget); config.LoggingRules.Add(rule1); LogManager.Configuration = config; }
public void VerifyInstalledGameFile(string file) { var src = Path.Combine(GameFolder, file); Assert.IsTrue(File.Exists(src), src); var dest = Path.Combine(InstallFolder, Consts.GameFolderFilesDir, file); Assert.IsTrue(File.Exists(dest), dest); var src_data = File.ReadAllBytes(src); var dest_data = File.ReadAllBytes(dest); Assert.AreEqual(src_data.Length, dest_data.Length); for (int x = 0; x < src_data.Length; x++) { if (src_data[x] != dest_data[x]) { Assert.Fail($"Index {x} of {Consts.GameFolderFilesDir}\\{file} are not the same"); } } }