/// <summary> /// Creates an instance of <see cref="ICompressedArchiveAccess"/> that can be used to access a nested archive. /// </summary> /// <param name="parentArchiveAccess">The parent archive, which contains the nested archive indicated by <paramref name="entry"/>.</param> /// <param name="entry">The entry within <paramref name="parentArchiveAccess"/> that indicates a nested archive.</param> /// <returns>An instance of <see cref="NestedCompressedArchiveAccess"/>, which provides access to the nested archive.</returns> /// <remarks>This wrapper type takes care of cleaning up any temporary files that may be required to access the nested archive. /// For example, some data streams used to access an archive are not navigable from the parent stream (GZIP).</remarks> public static NestedCompressedArchiveAccess Create(ICompressedArchiveAccess parentArchiveAccess, ICompressedArchiveEntry entry) { NestedCompressedArchiveAccess nestedCompressedArchive = null; var entryName = entry.Name; var nestedArchiveFormats = Path.GetExtension(entryName).GetCompressedArchiveFormatsFromFileExtension(); var nestedArchiveFormat = nestedArchiveFormats.FirstOrDefault(); if (nestedArchiveFormat.IsCompressedArchiveFormatSupported()) { TemporaryDirectory temporaryLocation = null; var entryData = parentArchiveAccess.OpenEntry(entry); if (FormatMustBeExtracted(parentArchiveAccess.Format) || FormatMustBeExtracted(nestedArchiveFormat)) { // We can't fully navigate the nested stream, so extract to disk, then proceed. temporaryLocation = new TemporaryDirectory(); var temporaryEntryFilePath = Path.Combine(temporaryLocation.Path, entryName); if (Directory.CreateDirectory(Path.GetDirectoryName(temporaryEntryFilePath)).Exists) { System.Diagnostics.Debug.WriteLine("Extracted entry " + entryName + " to " + temporaryLocation.Path); var fileStream = new FileStream(temporaryEntryFilePath, FileMode.Create, FileAccess.ReadWrite); entryData.CopyTo(fileStream); fileStream.Seek(0, SeekOrigin.Begin); entryData.Dispose(); entryData = fileStream; } } var compressedArchive = CompressedArchiveAccess.Open(entryData, nestedArchiveFormat, CompressedArchiveAccessMode.Read); nestedCompressedArchive = new NestedCompressedArchiveAccess(parentArchiveAccess, compressedArchive, temporaryLocation); nestedCompressedArchive.NestedArchiveFormats = nestedArchiveFormats; } return(nestedCompressedArchive); }
/// <inheritdoc /> protected override void Dispose(bool disposing) { lock (_lock) { if (CompressedArchiveAccess != null) { CompressedArchiveAccess.Dispose(); CompressedArchiveAccess = null; } if (Stream != null) { Stream.Dispose(); Stream = null; } } }
/// <inheritdoc /> public override ICompressedArchiveEntry CreateEntry(string name) { return(CompressedArchiveAccess.CreateEntry(name)); }
/// <inheritdoc /> protected override bool DeleteEntry(ICompressedArchiveEntry entry) { return(CompressedArchiveAccess.DeleteEntry(entry.Name)); }
/// <inheritdoc /> public override Stream OpenEntry(ICompressedArchiveEntry entry) { return(CompressedArchiveAccess.OpenEntry(entry)); }