0

I would like to see the percentage of each file zipping, I have tried incorrectly to solve this, here the code:

MainPaga.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 DestinationFolderPath = string.Empty;
string SourceFolderPath = string.Empty;

StorageFolder SourceFolder;
StorageFolder DestinationFolder;

public MainPage()
{
    this.InitializeComponent();
}

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)
    {
        try
        {
            string appFolderPath = ApplicationData.Current.LocalFolder.Path;
            StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", SourceFolder);

            //Gets the folder named TestFolder from Documents Library Folder  
            StorageFolder sourceFolder = SourceFolder;

            //Creates a zip file named TestFolder.zip in Local Folder  
            StorageFile zipFile = await DestinationFolder.CreateFileAsync("TestFolder.zip", CreationCollisionOption.ReplaceExisting);
            Stream zipToCreate = await zipFile.OpenStreamForWriteAsync();
            ZipArchive archive = new ZipArchive(zipToCreate, ZipArchiveMode.Create);

            await ZipFolderContentsHelper(sourceFolder, archive, sourceFolder.Path);
            archive.Dispose();
            MessageDialog msg = new MessageDialog("Success");
            await msg.ShowAsync();
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
        }
    }
}


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);
            await Task.Run(async () =>
            {
                await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
                {
                    double progress = entryStream.Position / buffer.Length;
                    TxbPercentage.Text = ((progress) * 100).ToString("0.00");
                });
            });
        }
    }

    IReadOnlyList<StorageFolder> subFolders = await sourceFolder.GetFoldersAsync();

    if (subFolders.Count() == 0)
    {
        return;
    }

    foreach (StorageFolder subfolder in subFolders)
    {
         await ZipFolderContentsHelper(subfolder, archive, sourceFolderPath);
    }
}

In the Stream in the ZipFolderContentsHelper method I opted for "entryStream.Position" but, this does not return the actual completed zipped size of the file... How can I proceed?

Always thanks in advance!

Jimmy
  • 45
  • 5

2 Answers2

0

The ZipArchiveFileEntry class provides the Properties Lenght and CompressedLength. You can use those proerties to calculate the compression ratio. If you'll go with your approach, you hae to cast one of the length to a double before assigning it (double progress = (double) entryStream.Position / buffer.Length). But i'm not sure if that will yield to the correct result.

Pretasoc
  • 1,116
  • 12
  • 22
  • I found perhaps an example, but I can not adapt it because in this [example](https://stackoverflow.com/questions/42430559/progress-bar-not-available-for-zipfile-how-to-give-feedback-when-program-seems) for the zip file we use the path in string and not the storage file but, it could be useful for the solution – Jimmy Sep 21 '18 at 13:06
  • Could you give an example of your answer? – Jimmy Sep 22 '18 at 06:18
0

In the Stream in the ZipFolderContentsHelper method I opted for "entryStream.Position" but, this does not return the actual completed size of the file... How can I proceed?

If your final requirement is to get the size of the zipped file. You could get it by using the StorageFile.Properties.

Then, you could call the StorageFile.GetBasicPropertiesAsync method. This method returns a BasicProperties object, which defines properties for the size of the item (file or folder) as well as when the item was last modified.

More information, please read Getting a file's basic properties for details.

[Updated on 2018/9/25]

No I would not like to find the file size, but view the progress of the single file's zip.

With your code, the entryStream.Position always equals to buffer.Length and the ZipArchive class doesn't include progress reporting. So, what you need to think about is reporting progress for async task in your code by yourself.

Please see the relevant information: Enabling Progress and Cancellation in Async APIs and the relevant thread How to do progress reporting using Async/Await.

Xie Steven
  • 8,544
  • 1
  • 9
  • 23
  • No I would not like to find the file size, but view the progress of the single file's zip. – Jimmy Sep 24 '18 at 14:04