Создать сжатую папку UWP - PullRequest
       10

Создать сжатую папку UWP

0 голосов
/ 12 сентября 2018

Создать сжатую папку

Я хочу заархивировать папку, я пытался написать код, который должен это сделать, но я получаю сообщение об ошибке, что папка пуста:

  1. Создать пустой почтовый файл.
  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);
        }
    }
}

Хотя в потоке есть запись, он создает пустой и недоступный файл.

Заранее спасибо!

1 Ответ

0 голосов
/ 13 сентября 2018

Для вашего сценария вы можете использовать метод 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 вызывается из метода WindowsRuntimeBufferExtensions ToArray, который ожидает, что размер 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);
    }
}

Это пример кода , который вы можете использовать напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...