Есть программка. В нее зашит 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");
Комментариев нет:
Отправить комментарий