예제 #1
0
            /// <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);
            }
예제 #2
0
 /// <inheritdoc />
 protected override void Dispose(bool disposing)
 {
     lock (_lock)
     {
         if (CompressedArchiveAccess != null)
         {
             CompressedArchiveAccess.Dispose();
             CompressedArchiveAccess = null;
         }
         if (Stream != null)
         {
             Stream.Dispose();
             Stream = null;
         }
     }
 }
예제 #3
0
 /// <inheritdoc />
 public override ICompressedArchiveEntry CreateEntry(string name)
 {
     return(CompressedArchiveAccess.CreateEntry(name));
 }
예제 #4
0
 /// <inheritdoc />
 protected override bool DeleteEntry(ICompressedArchiveEntry entry)
 {
     return(CompressedArchiveAccess.DeleteEntry(entry.Name));
 }
예제 #5
0
 /// <inheritdoc />
 public override Stream OpenEntry(ICompressedArchiveEntry entry)
 {
     return(CompressedArchiveAccess.OpenEntry(entry));
 }