创建压缩文件夹 UWP



创建压缩文件夹

我想压缩一个文件夹,我尝试编写应该执行此操作的代码,但是我收到该文件夹为空的错误:

  1. 创建空的 zip 文件。
  2. 不允许我从zip文件中提取文件(它 告诉我,事实上,该文件夹是空的(。

MainPage.xaml

<Grid>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal" Margin="5">
<Button x:Name="BtnChooseFolder" Click="BtnChooseFolder_Click" Content="Choose Folder" Margin="5"/>
<TextBlock Text="Folder to Zip: " VerticalAlignment="Center"/>
<TextBlock x:Name="TxbFolderToZip" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5">
<Button x:Name="BtnChooseDestination" Click="BtnChooseDestination_Click" Content="Choose Destination" Margin="5"/>
<TextBlock Text="Zip Folder: " VerticalAlignment="Center"/>
<TextBlock x:Name="TxbZipFolder" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button x:Name="BtnZip" Click="BtnZip_Click" Content="Zippa" Margin="10"/>
<TextBlock x:Name="TxbPercentage" VerticalAlignment="Center"/>
</StackPanel>
</StackPanel>
</Grid>

MainPage.xaml.cs

string FolderPathOne = string.Empty;
string FoldeDestinationOne = string.Empty;
StorageFolder FolderPath;
StorageFolder DestinationPath;
public MainPage()
{
this.InitializeComponent();
}
private async void BtnChooseFolder_Click(object sender, RoutedEventArgs e)
{
FolderPicker FolderPickFol = new FolderPicker();
FolderPickFol.SuggestedStartLocation = PickerLocationId.Desktop;
FolderPickFol.FileTypeFilter.Add("*");
StorageFolder SelectFolderToZipa = await FolderPickFol.PickSingleFolderAsync();
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolder", SelectFolderToZipa);
FolderPath = SelectFolderToZipa;
FolderPathOne = SelectFolderToZipa.Path;
TxbFolderToZip.Text = FolderPathOne;
}
private async void BtnChooseDestination_Click(object sender, RoutedEventArgs e)
{
FolderPicker FolderPickFol = new FolderPicker();
FolderPickFol.SuggestedStartLocation = PickerLocationId.Desktop;
FolderPickFol.FileTypeFilter.Add("*");
StorageFolder SelectFolderToZipa = await FolderPickFol.PickSingleFolderAsync();
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedDestination", SelectFolderToZipa);
DestinationPath = SelectFolderToZipa;
FoldeDestinationOne = SelectFolderToZipa.Path;
TxbZipFolder.Text = FoldeDestinationOne;
}
private async void BtnZip_Click(object sender, RoutedEventArgs e)
{
StorageFile zipFile = await DestinationPath.CreateFileAsync("ZipFolderTest.zip", CreationCollisionOption.ReplaceExisting);
Stream zipToCreate = await zipFile.OpenStreamForWriteAsync();
ZipArchive archive = new ZipArchive(zipToCreate, ZipArchiveMode.Update);
await ZipFolderContents(FolderPath, archive, FolderPath.Path);
}
private async Task ZipFolderContents(StorageFolder sourceFolder, ZipArchive archive, string sourceFolderPath)
{
IReadOnlyList<StorageFile> files = await sourceFolder.GetFilesAsync();
foreach (StorageFile file in files)
{
ZipArchiveEntry readmeEntry = archive.CreateEntry(file.Path.Remove(0, sourceFolderPath.Length));
byte[] buffer = WindowsRuntimeBufferExtensions.ToArray(await FileIO.ReadBufferAsync(file));
using (Stream entryStream = readmeEntry.Open())
{
await entryStream.WriteAsync(buffer, 0, buffer.Length);
}
}
}

尽管流中有写入,但它会创建空且无法访问的文件。

提前感谢!

对于你的方案,可以使用ZipFile.CreateFromDirectory方法直接压缩文件夹。

string DestinationFolderPath = string.Empty;
string SourceFolderPath = string.Empty;
StorageFolder SourceFolder;
StorageFolder DestinationFolder;
private async void BtnChooseFolder_Click(object sender, RoutedEventArgs e)
{
FolderPicker FolderPickFol = new FolderPicker();
FolderPickFol.SuggestedStartLocation = PickerLocationId.Desktop;
FolderPickFol.FileTypeFilter.Add("*");
Windows.Storage.StorageFolder SelectFolderToZipa = await FolderPickFol.PickSingleFolderAsync();
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolder", SelectFolderToZipa);
SourceFolder = SelectFolderToZipa;
SourceFolderPath = SelectFolderToZipa.Path;
TxbFolderToZip.Text = SourceFolderPath;
}
private async void BtnChooseDestination_Click(object sender, RoutedEventArgs e)
{
FolderPicker FolderPickFol = new FolderPicker();
FolderPickFol.SuggestedStartLocation = PickerLocationId.Desktop;
FolderPickFol.FileTypeFilter.Add("*");
StorageFolder SelectFolderToZipa = await FolderPickFol.PickSingleFolderAsync();
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedDestination", SelectFolderToZipa);
DestinationFolder = SelectFolderToZipa;
DestinationFolderPath = SelectFolderToZipa.Path;
TxbZipFolder.Text = DestinationFolderPath;
}
private async void BtnZip_Click(object sender, RoutedEventArgs e)
{
if (SourceFolder != null)
{
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", SourceFolder);
await Task.Run(() =>
{
try
{
System.IO.Compression.ZipFile.CreateFromDirectory(SourceFolderPath, $"{DestinationFolderPath}\{SourceFolder.Name}.zip");
}
catch (Exception w)
{
}
});
}
}

对于此方法,您只需传递源文件夹路径和目标 zip 文件 两个参数。

ZipFile.CreateFromDirectory(SourceFolderPath, $"{DestinationFolderPath}\{SourceFolder.Name}.zip");

上面的代码是根据您的帖子编辑的,您可以直接在您的项目中使用它。

更新

从这个案例中衍生出来。

此 System.ArgumentException 是从WindowsRuntimeBufferExtensionsToArray 方法引发的,该方法期望 IBuffer 的大小大于 0。

所以我用以下方法替换它

private async Task ZipFolderContentsHelper(StorageFolder sourceFolder, ZipArchive archive, string sourceFolderPath)
{
IReadOnlyList<StorageFile> files = await sourceFolder.GetFilesAsync();
foreach (StorageFile file in files)
{
var path = file.Path.Remove(0, sourceFolderPath.Length);
ZipArchiveEntry readmeEntry = archive.CreateEntry(file.Path.Remove(0, sourceFolderPath.Length));
ulong fileSize = (await file.GetBasicPropertiesAsync()).Size;
byte[] buffer = fileSize > 0 ? (await FileIO.ReadBufferAsync(file)).ToArray()
: new byte[0];

using (Stream entryStream = readmeEntry.Open())
{
await entryStream.WriteAsync(buffer, 0, buffer.Length);
}
}
IReadOnlyList<StorageFolder> subFolders = await sourceFolder.GetFoldersAsync();
if (subFolders.Count() == 0)
{
return;
}
foreach (StorageFolder subfolder in subFolders)
{
await ZipFolderContentsHelper(subfolder, archive, sourceFolderPath);
}
}

这是可以直接使用的代码示例。

最新更新