Страницы

Поиск по вопросам

пятница, 11 января 2019 г.

Как распаковать архив из ресурсов одним действием?

Есть программка. В нее зашит Zip архив. Сначала у меня происходит извлечение ресурса во временную папку
File.WriteAllBytes(fileName, (byte[])Properties.Resources.ResourceManager.GetObject(res.Key));
Затем уже архив распаковывается
ZipFile.ExtractToDirectory(Path.Combine(TempDir, fileName), libsPath);
Оба процесса занимают по 10 секунд. А как можно сразу распаковать архив из ресурсов, не имея файл на диске? Если, конечно, это возможно.


Ответ

Возможно, например. Для работы с Zip архивами использую библиотеку SharpZipLib. Ставится легко и быстро через Nuget.
Взяв отсюда пример по распаковке Zip-архива, написал такую функцию(чуточку переделал ее)
public static void ExtractZipFile(Stream inputStream, string password, string outFolder) { ZipFile zf = null; try { zf = new ZipFile(inputStream); if (!string.IsNullOrEmpty(password)) { zf.Password = password; // AES encrypted entries are handled automatically } foreach (ZipEntry zipEntry in zf) { if (!zipEntry.IsFile) { continue; // Ignore directories } String entryFileName = zipEntry.Name; // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName); // Optionally match entrynames against a selection list here to skip as desired. // The unpacked length is available in the zipEntry.Size property.
byte[] buffer = new byte[4096]; // 4K is optimum Stream zipStream = zf.GetInputStream(zipEntry);
// Manipulate the output filename here as desired. String fullZipToPath = Path.Combine(outFolder, entryFileName); string directoryName = Path.GetDirectoryName(fullZipToPath); if (directoryName.Length > 0) Directory.CreateDirectory(directoryName);
// Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size // of the file, but does not waste memory. // The "using" will close the stream even if an exception occurs. using (FileStream streamWriter = File.Create(fullZipToPath)) { StreamUtils.Copy(zipStream, streamWriter, buffer); } } } finally { if (zf != null) { zf.IsStreamOwner = true; // Makes close also shut the underlying stream zf.Close(); // Ensure we release resources } } }
Теперь, создав из массива байт поток, можно вызвать эту функцию следующим образом
Stream stream = new MemoryStream(byteArray); stream.Position = 0; ExtractZipFile(stream, "", @"DestFolder");

Комментариев нет:

Отправить комментарий