ArchiveFactory.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. using System;
  2. using System.IO;
  3. using SharpCompress.Archives.GZip;
  4. using SharpCompress.Archives.Rar;
  5. using SharpCompress.Archives.SevenZip;
  6. using SharpCompress.Archives.Tar;
  7. using SharpCompress.Archives.Zip;
  8. using SharpCompress.Common;
  9. using SharpCompress.Compressors.LZMA;
  10. using SharpCompress.Readers;
  11. namespace SharpCompress.Archives
  12. {
  13. public class ArchiveFactory
  14. {
  15. /// <summary>
  16. /// Opens an Archive for random access
  17. /// </summary>
  18. /// <param name="stream"></param>
  19. /// <param name="readerOptions"></param>
  20. /// <returns></returns>
  21. public static IArchive Open(Stream stream, ReaderOptions readerOptions = null)
  22. {
  23. stream.CheckNotNull("stream");
  24. if (!stream.CanRead || !stream.CanSeek)
  25. {
  26. throw new ArgumentException("Stream should be readable and seekable");
  27. }
  28. readerOptions = readerOptions ?? new ReaderOptions();
  29. if (ZipArchive.IsZipFile(stream, null))
  30. {
  31. stream.Seek(0, SeekOrigin.Begin);
  32. return ZipArchive.Open(stream, readerOptions);
  33. }
  34. stream.Seek(0, SeekOrigin.Begin);
  35. if (SevenZipArchive.IsSevenZipFile(stream))
  36. {
  37. stream.Seek(0, SeekOrigin.Begin);
  38. return SevenZipArchive.Open(stream, readerOptions);
  39. }
  40. stream.Seek(0, SeekOrigin.Begin);
  41. if (GZipArchive.IsGZipFile(stream))
  42. {
  43. stream.Seek(0, SeekOrigin.Begin);
  44. return GZipArchive.Open(stream, readerOptions);
  45. }
  46. stream.Seek(0, SeekOrigin.Begin);
  47. if (RarArchive.IsRarFile(stream, readerOptions))
  48. {
  49. stream.Seek(0, SeekOrigin.Begin);
  50. return RarArchive.Open(stream, readerOptions);
  51. }
  52. stream.Seek(0, SeekOrigin.Begin);
  53. if (TarArchive.IsTarFile(stream))
  54. {
  55. stream.Seek(0, SeekOrigin.Begin);
  56. return TarArchive.Open(stream, readerOptions);
  57. }
  58. throw new InvalidOperationException("Cannot determine compressed stream type. Supported Archive Formats: Zip, GZip, Tar, Rar, 7Zip, LZip");
  59. }
  60. public static IWritableArchive Create(ArchiveType type)
  61. {
  62. switch (type)
  63. {
  64. case ArchiveType.Zip:
  65. {
  66. return ZipArchive.Create();
  67. }
  68. case ArchiveType.Tar:
  69. {
  70. return TarArchive.Create();
  71. }
  72. case ArchiveType.GZip:
  73. {
  74. return GZipArchive.Create();
  75. }
  76. default:
  77. {
  78. throw new NotSupportedException("Cannot create Archives of type: " + type);
  79. }
  80. }
  81. }
  82. #if !NO_FILE
  83. /// <summary>
  84. /// Constructor expects a filepath to an existing file.
  85. /// </summary>
  86. /// <param name="filePath"></param>
  87. /// <param name="options"></param>
  88. public static IArchive Open(string filePath, ReaderOptions options = null)
  89. {
  90. filePath.CheckNotNullOrEmpty("filePath");
  91. return Open(new FileInfo(filePath), options ?? new ReaderOptions());
  92. }
  93. /// <summary>
  94. /// Constructor with a FileInfo object to an existing file.
  95. /// </summary>
  96. /// <param name="fileInfo"></param>
  97. /// <param name="options"></param>
  98. public static IArchive Open(FileInfo fileInfo, ReaderOptions options = null)
  99. {
  100. fileInfo.CheckNotNull("fileInfo");
  101. options = options ?? new ReaderOptions();
  102. using (var stream = fileInfo.OpenRead())
  103. {
  104. if (ZipArchive.IsZipFile(stream, null))
  105. {
  106. stream.Dispose();
  107. return ZipArchive.Open(fileInfo, options);
  108. }
  109. stream.Seek(0, SeekOrigin.Begin);
  110. if (SevenZipArchive.IsSevenZipFile(stream))
  111. {
  112. stream.Dispose();
  113. return SevenZipArchive.Open(fileInfo, options);
  114. }
  115. stream.Seek(0, SeekOrigin.Begin);
  116. if (GZipArchive.IsGZipFile(stream))
  117. {
  118. stream.Dispose();
  119. return GZipArchive.Open(fileInfo, options);
  120. }
  121. stream.Seek(0, SeekOrigin.Begin);
  122. if (RarArchive.IsRarFile(stream, options))
  123. {
  124. stream.Dispose();
  125. return RarArchive.Open(fileInfo, options);
  126. }
  127. stream.Seek(0, SeekOrigin.Begin);
  128. if (TarArchive.IsTarFile(stream))
  129. {
  130. stream.Dispose();
  131. return TarArchive.Open(fileInfo, options);
  132. }
  133. throw new InvalidOperationException("Cannot determine compressed stream type. Supported Archive Formats: Zip, GZip, Tar, Rar, 7Zip");
  134. }
  135. }
  136. /// <summary>
  137. /// Extract to specific directory, retaining filename
  138. /// </summary>
  139. public static void WriteToDirectory(string sourceArchive, string destinationDirectory,
  140. ExtractionOptions options = null)
  141. {
  142. using (IArchive archive = Open(sourceArchive))
  143. {
  144. foreach (IArchiveEntry entry in archive.Entries)
  145. {
  146. entry.WriteToDirectory(destinationDirectory, options);
  147. }
  148. }
  149. }
  150. #endif
  151. }
  152. }