Процент Zip файла UWP - PullRequest
       3

Процент Zip файла UWP

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

Я бы хотел видеть процентное соотношение каждого архивируемого файла, я пытался решить эту проблему неправильно, вот код:

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

В потоке в методе ZipFolderContentsHelper я выбрал "entryStream.Position", но это не возвращает фактическое завершениеразмер файла в архиве ... Как продолжить?

Всегда заранее спасибо!

Ответы [ 2 ]

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

В потоке в методе ZipFolderContentsHelper я выбрал "entryStream.Position", но это не возвращает фактический завершенный размер файла ... Как я могу продолжить?

Если ваше последнее требование заключается в том, чтобы получить размер сжатого файла.Вы можете получить его, используя StorageFile.Properties .

Затем вы можете вызвать метод StorageFile.GetBasicPropertiesAsync .Этот метод возвращает объект BasicProperties, который определяет свойства для размера элемента (файла или папки), а также времени последнего изменения элемента.

Дополнительную информацию см. В Получение основных свойств файла для подробностей.

[Обновлено 2019/9/25]

Нет Я не хотел бы находитьразмер файла, но просмотрите ход zip-файла одного файла.

С вашим кодом entryStream.Position всегда равен buffer.Length, а класс ZipArchive не включает отчеты о ходе выполнения.Итак, вам нужно подумать о том, как самостоятельно сообщать о ходе выполнения асинхронной задачи в вашем коде.

Пожалуйста, ознакомьтесь с соответствующей информацией: Включение выполнения и отмены в API-интерфейсах асинхронной обработки и соответствующей веткой Как создавать отчеты о прогрессе с помощью Async / Await .

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

Класс ZipArchiveFileEntry предоставляет свойства Lenght и CompressedLength.Вы можете использовать эти свойства для расчета степени сжатия.Если вы пойдете со своим подходом, вы должны привести одну из длин к double перед тем, как назначить его (double progress = (double) entryStream.Position / buffer.Length).Но я не уверен, что это даст правильный результат.

...