压缩文件百分比UWP

时间:2018-09-21 12:21:50

标签: c# uwp zip percentage

我想查看每个文件的压缩百分比,但我尝试了错误的解决方法,这里的代码为:

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);
    }
}
  

在Stream中的ZipFolderContentsHelper方法中,我选择了“ entryStream.Position”,但是,这没有返回文件的实际已完成的压缩大小。如何继续?

总是提前谢谢!

2 个答案:

答案 0 :(得分:0)

ZipArchiveFileEntry类提供属性LenghtCompressedLength。您可以使用这些属性来计算压缩率。如果您采用自己的方法,则必须在分配长度(double之前将长度的其中之一强制转换为double progress = (double) entryStream.Position / buffer.Length。但是我不确定这是否会产生正确的结果。

答案 1 :(得分:0)

  

在ZipFolderContentsHelper方法的Stream中,我选择了“ entryStream.Position”,但是,这没有返回文件的实际完成大小...我该如何进行?

如果您的最终要求是获取压缩文件的大小。您可以使用StorageFile.Properties来获取它。

然后,您可以调用StorageFile.GetBasicPropertiesAsync方法。此方法返回BasicProperties对象,该对象定义项目(文件或文件夹)的大小以及上次修改项目的时间的属性。

更多信息,请阅读Getting a file's basic properties了解详情。

[于2018/9/25更新]

  

否,我不想找到文件大小,但要查看单个文件zip的进度。

对于您的代码,if y ne . then output; 始终等于entryStream.Position,而buffer.Length类不包含进度报告。因此,您需要考虑的是自己在代码中报告异步任务的进度。

请参阅相关信息:Enabling Progress and Cancellation in Async APIs和相关线程How to do progress reporting using Async/Await