从 UWP 中的存档中提取特定文件
Extracting specific File from archive in UWP
为了保存 space,我在我的 UWP 项目中压缩了我的书籍(xml 格式)。我想根据文件名将文件提取到我的本地文件夹。
到目前为止我所做的(这会提取所有文件):
ZipFile.ExtractToDirectory(sourceCompressedFile.Path, destinationFolder.Path);
然而,这会将我存档中的所有文件提取到我的目标文件夹中。我知道使用 SharpZipLib 这可能是一项微不足道的任务,但这是一种内置方法,可以帮助我减小应用程序的大小。我只是想提取一个名称与我提供的名称匹配的文件。除了这个还有其他三种方法,但我迷路了。
这可以使用 DotNetZip 轻松完成 here 但我不想使用任何第三方库
我想你有几个文件压缩在一个 zip 存档中,因此 ZipFile.ExtractToDirectory Method (String, String) 会将指定 zip 存档中的所有文件解压缩到一个目录中。
如果你只想访问这个压缩包中的一个特殊文件,你可以使用ZipArchiveEntry Class来完成这项工作,例如这里:
StorageFolder _folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
/*fails here FileNotFound*/
StorageFile sourceCompressedFile = await _folder.GetFileAsync("archived.zip");
StorageFolder folder = ApplicationData.Current.LocalFolder;
// ZipFile.ExtractToDirectory(file.Path, folder.Path);
using (ZipArchive archive = ZipFile.OpenRead(sourceCompressedFile.Path))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.FullName.ToString() == "miao2.jpg")
{
entry.ExtractToFile(Path.Combine(folder.Path, entry.FullName));
}
}
}
我压缩了几张图片作为"archived.zip"文件进行测试,在这个示例中,它只会提取名为"miao2.jpg"的图像文件。
好的...知道了!
首先,要阅读特定条目,请使用 ZipArchiveEntry.GetEntry(entrytosearch);
其次,无法将 ZipArchiveEntry 读入 IRandomAccessStream,我不知道为什么...摆弄了好一阵子才决定先在内存中读取它。由于我正在做的是读取图像以显示在屏幕上,因此它对内存管理的影响有限。但是,如果您正在阅读大的内容,请注意大小。在阅读之前,我会检查条目的 .Length。但是,为了简单起见,这里是更新的代码,用于将 zip 文件的特定“.jpg”条目读入 Image.Source。
尚不优雅或复杂,但我希望它可以节省别人我花在摆弄这个上的时间!
public class ZipItem
{
public StorageFile motherfile { get; set; }
public ZipArchiveEntry motherentry { get; set; }
public string Name { get; set; }
public string ActualBytes { get; set; }
public string CompressedBytes { get; set; }
}
public List<ZipItem> results;
public int i = 0;
private async void nextimg_Click(object sender, RoutedEventArgs e)
{
//Open the zip file. At that point in the program, I previously read
//all zip files in a hierarchy and stored them in the "results" a
//list of ZipItems populated in another method. i points to the
//image I wish to display in the list.
Stream stream = await results[i].motherfile.OpenStreamForReadAsync();
using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read))
{
//look for the entry "i", which is my current slideshow position
ZipArchiveEntry entry = archive.GetEntry(results[i].motherentry.Name);
//Open the entry as a stream
Stream fileStream = entry.Open();
//Before I read this in memory, I do check for entry.Length to make sure it's not too big.
//For simplicity purposes here, I jsut show the "Read it in memory" portion
var memStream = new MemoryStream();
await fileStream.CopyToAsync(memStream);
//Reset the stream position to start
memStream.Position = 0;
//Create a BitmapImage from the memStream;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.DecodePixelHeight = (int)ctlImage.Height;
bitmapImage.DecodePixelWidth = (int)ctlImage.Width;
//Set the source of the BitmapImage to the memory stream
bitmapImage.SetSource(memStream.AsRandomAccessStream());
//Set the Image.Source to the BitmapImage
ctlImage.Source = bitmapImage;
}
}
}
为了保存 space,我在我的 UWP 项目中压缩了我的书籍(xml 格式)。我想根据文件名将文件提取到我的本地文件夹。
到目前为止我所做的(这会提取所有文件):
ZipFile.ExtractToDirectory(sourceCompressedFile.Path, destinationFolder.Path);
然而,这会将我存档中的所有文件提取到我的目标文件夹中。我知道使用 SharpZipLib 这可能是一项微不足道的任务,但这是一种内置方法,可以帮助我减小应用程序的大小。我只是想提取一个名称与我提供的名称匹配的文件。除了这个还有其他三种方法,但我迷路了。
这可以使用 DotNetZip 轻松完成 here 但我不想使用任何第三方库
我想你有几个文件压缩在一个 zip 存档中,因此 ZipFile.ExtractToDirectory Method (String, String) 会将指定 zip 存档中的所有文件解压缩到一个目录中。
如果你只想访问这个压缩包中的一个特殊文件,你可以使用ZipArchiveEntry Class来完成这项工作,例如这里:
StorageFolder _folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
/*fails here FileNotFound*/
StorageFile sourceCompressedFile = await _folder.GetFileAsync("archived.zip");
StorageFolder folder = ApplicationData.Current.LocalFolder;
// ZipFile.ExtractToDirectory(file.Path, folder.Path);
using (ZipArchive archive = ZipFile.OpenRead(sourceCompressedFile.Path))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.FullName.ToString() == "miao2.jpg")
{
entry.ExtractToFile(Path.Combine(folder.Path, entry.FullName));
}
}
}
我压缩了几张图片作为"archived.zip"文件进行测试,在这个示例中,它只会提取名为"miao2.jpg"的图像文件。
好的...知道了!
首先,要阅读特定条目,请使用 ZipArchiveEntry.GetEntry(entrytosearch);
其次,无法将 ZipArchiveEntry 读入 IRandomAccessStream,我不知道为什么...摆弄了好一阵子才决定先在内存中读取它。由于我正在做的是读取图像以显示在屏幕上,因此它对内存管理的影响有限。但是,如果您正在阅读大的内容,请注意大小。在阅读之前,我会检查条目的 .Length。但是,为了简单起见,这里是更新的代码,用于将 zip 文件的特定“.jpg”条目读入 Image.Source。
尚不优雅或复杂,但我希望它可以节省别人我花在摆弄这个上的时间!
public class ZipItem
{
public StorageFile motherfile { get; set; }
public ZipArchiveEntry motherentry { get; set; }
public string Name { get; set; }
public string ActualBytes { get; set; }
public string CompressedBytes { get; set; }
}
public List<ZipItem> results;
public int i = 0;
private async void nextimg_Click(object sender, RoutedEventArgs e)
{
//Open the zip file. At that point in the program, I previously read
//all zip files in a hierarchy and stored them in the "results" a
//list of ZipItems populated in another method. i points to the
//image I wish to display in the list.
Stream stream = await results[i].motherfile.OpenStreamForReadAsync();
using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read))
{
//look for the entry "i", which is my current slideshow position
ZipArchiveEntry entry = archive.GetEntry(results[i].motherentry.Name);
//Open the entry as a stream
Stream fileStream = entry.Open();
//Before I read this in memory, I do check for entry.Length to make sure it's not too big.
//For simplicity purposes here, I jsut show the "Read it in memory" portion
var memStream = new MemoryStream();
await fileStream.CopyToAsync(memStream);
//Reset the stream position to start
memStream.Position = 0;
//Create a BitmapImage from the memStream;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.DecodePixelHeight = (int)ctlImage.Height;
bitmapImage.DecodePixelWidth = (int)ctlImage.Width;
//Set the source of the BitmapImage to the memory stream
bitmapImage.SetSource(memStream.AsRandomAccessStream());
//Set the Image.Source to the BitmapImage
ctlImage.Source = bitmapImage;
}
}
}