/// <summary> /// Открыть Xml файл /// </summary> /// <param name="path">Путь к файлу в папке Resourse</param> public void OpenFile() { TextAsset textAsset = Resources.Load <TextAsset>(Path); fileXml = new XmlDocument(); FileXml.LoadXml(textAsset.text); }
private static void CheckHash(string tempPath, FileXml metadata) { if (CheckHash(tempPath, metadata.sha1, () => SHA1.Create())) { return; } if (CheckHash(tempPath, metadata.md5, () => MD5.Create())) { return; } // TODO: CRC is not built into .net. Are there archive items without neither sha1, nor md5? Utils.WriteLog($"Warning! No hash information is available for ${metadata.name}."); }
public static async Task DownloadFileToStagingAsync(string archiveItem, string relativePath, FileXml metadata) { var expectedSize = metadata?.size; var outputPath = Path.Combine(Program.StagingFolder, archiveItem, relativePath); if (File.Exists(outputPath)) { return; } var tempPath = outputPath + ".tmp"; Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); Utils.WriteLog($"Retrieving {archiveItem}/{relativePath}" + (expectedSize != null ? $" ({new FileSize(expectedSize.Value)})" : null)); using var response = await Utils.httpClient.GetAsync($"https://archive.org/download/{archiveItem}/{relativePath}", HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); var lastModified = response.Content.Headers.LastModified; if (lastModified == null) { throw new Exception($"Server did not return a Last-Modified header for '{archiveItem}/{relativePath}'."); } var lastProgressPrint = Stopwatch.StartNew(); using var stream = await response.Content.ReadAsStreamAsync(); using (var tempStream = File.Create(tempPath)) { var buffer = new byte[1 * 1024 * 1024]; var totalRead = 0L; while (true) { var read = await stream.ReadAsync(buffer); if (read == 0) { break; } await tempStream.WriteAsync(buffer, 0, read); totalRead += read; if (lastProgressPrint.ElapsedMilliseconds > 30_000) { Utils.WriteLog(" " + new FileSize(totalRead) + " of " + (expectedSize != null ? new FileSize(expectedSize.Value).ToString() : "unknown")); lastProgressPrint.Restart(); } } } var actualFileLength = new FileInfo(tempPath).Length; if (expectedSize != null && actualFileLength != expectedSize) { throw new Exception($"Unexpected size for item '{archiveItem}/{relativePath}': {expectedSize} according to metadata, but retrieved {actualFileLength}."); } if (metadata != null) { CheckHash(tempPath, metadata); } File.SetLastWriteTimeUtc(tempPath, lastModified.Value.UtcDateTime); File.Move(tempPath, outputPath, overwrite: true); }
public static async Task RetryDownloadFileToStagingAsync(string archiveItem, string relativePath, FileXml metadata) { var delay = 10; var attempts = 0; while (true) { attempts++; try { await DownloadFileToStagingAsync(archiveItem, relativePath, metadata); return; } catch (Exception ex) { Utils.WriteLog($"Download failed for {archiveItem}/{relativePath}: " + Utils.GetMessageForException(ex)); if (attempts == 10) { throw; } Utils.WriteLog($"Retrying in {delay} seconds."); delay *= 2; } } }