Reputation: 1962
I have a xamarin form application in which there is option for creating a zip file. I use SharpZipLib.Portable plugin to create the zip file. I used the same sample explained here for creating the zip file. I need to add progress bar to this application. I do this:
double FilesCount=0;
double CopyCount = 0;
private void CreateZipFile()
{
string Folder = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).Path;
FilesCount = Directory.GetFileSystemEntries(Folder).Count();
string ZipFilePath = Path.Combine(Folder, "File.zip");
CreateSample(ZipFilePath, Folder);
}
public async void CreateSample(string outPathname, string folderName)
{
FileStream fsOut = File.Create(outPathname);
ZipOutputStream zipStream = new ZipOutputStream(fsOut);
zipStream.SetLevel(3);
zipStream.Password = null;
int folderOffset = folderName.Length + (folderName.EndsWith("\\") ? 0 : 1);
CompressFolderAsync(folderName, zipStream, folderOffset);
zipStream.IsStreamOwner = true;
zipStream.Close();
await DisplayAlert("Creating Backup", "Creating backup is completed successfully. The buckup file is store in the following path: " + outPathname, "Ok");
}
private void CompressFolderAsync(string path, ZipOutputStream zipStream, int folderOffset)
{
string[] files = Directory.GetFiles(path);
foreach (string filename in files)
{
FileInfo fi = new FileInfo(filename);
string entryName = filename.Substring(folderOffset);
entryName = ZipEntry.CleanName(entryName);
ZipEntry newEntry = new ZipEntry(entryName);
newEntry.DateTime = fi.LastWriteTime;
newEntry.Size = fi.Length;
zipStream.PutNextEntry(newEntry);
byte[] buffer = new byte[4096];
using (FileStream streamReader = File.OpenRead(filename))
{
StreamUtils.Copy(streamReader, zipStream, buffer);
}
zipStream.CloseEntry();
}
CopyCount += 1;
CreateBackupProgress.ProgressTo(CopyCount / FilesCount, 800, Easing.Linear);
string[] folders = Directory.GetDirectories(path);
foreach (string folder in folders)
{
CompressFolderAsync(folder, zipStream, folderOffset);
}
}
The problem is that the progress bar doesn't animated until the process finish. I tried to make the method async as follow:
await CreateBackupProgress.ProgressTo(CopyCount / FilesCount, 800, Easing.Linear);
But also not worked. I try using Task.Run()
to make method works in background. This is the code:
private async void CompressFolderAsync(string path, ZipOutputStream zipStream, int folderOffset)
{
string[] files = Directory.GetFiles(path);
await Task.Run(() => {
foreach (string filename in files)
{
FileInfo fi = new FileInfo(filename);
string entryName = filename.Substring(folderOffset);
entryName = ZipEntry.CleanName(entryName);
ZipEntry newEntry = new ZipEntry(entryName);
newEntry.DateTime = fi.LastWriteTime;
newEntry.Size = fi.Length;
zipStream.PutNextEntry(newEntry);
byte[] buffer = new byte[4096];
using (FileStream streamReader = File.OpenRead(filename))
{
StreamUtils.Copy(streamReader, zipStream, buffer);
}
zipStream.CloseEntry();
}
CopyCount += 1;
CreateBackupProgress.ProgressTo(CopyCount / FilesCount, 100, Easing.Linear);
});
string[] folders = Directory.GetDirectories(path);
foreach (string folder in folders)
{
CompressFolderAsync(folder, zipStream, folderOffset);
}
}
But I get this error:
Unhandled Exception: System.InvalidOperationException: ZipOutputStream was finished occurred
How can I solve this problem?
Upvotes: 1
Views: 458
Reputation: 1962
The problem solved by using this:
double FilesCount = 0;
double CopyCount = 0;
public async void CreateSample(string outPathname, string folderName)
{
FileStream fsOut = File.Create(outPathname);
ZipOutputStream zipStream = new ZipOutputStream(fsOut);
zipStream.SetLevel(3);
zipStream.Password = null;
int folderOffset = folderName.Length + (folderName.EndsWith("\\") ? 0 : 1);
CreateBackupProgress.IsVisible = true;
Task task1 = new Task(CheckProgressbar);
task1.Start();
Task task2 = new Task(() => CompressFolderAsync(folderName, zipStream, folderOffset));
task2.Start();
await task1;
await task2;
zipStream.IsStreamOwner = true;
zipStream.Close();
await DisplayAlert("Creating Backup", "Creating backup is completed successfully. The buckup file is store in the following path: " + outPathname, "Ok");
}
private void CompressFolderAsync(string path, ZipOutputStream zipStream, int folderOffset)
{
string[] files = Directory.GetFiles(path);
foreach (string filename in files)
{
FileInfo fi = new FileInfo(filename);
string entryName = filename.Substring(folderOffset);
entryName = ZipEntry.CleanName(entryName);
ZipEntry newEntry = new ZipEntry(entryName);
newEntry.DateTime = fi.LastWriteTime;
newEntry.Size = fi.Length;
zipStream.PutNextEntry(newEntry);
byte[] buffer = new byte[4096];
using (FileStream streamReader = File.OpenRead(filename))
{
StreamUtils.Copy(streamReader, zipStream, buffer);
}
zipStream.CloseEntry();
}
CopyCount += 1;
string[] folders = Directory.GetDirectories(path);
foreach (string folder in folders)
{
CompressFolderAsync(folder, zipStream, folderOffset);
}
}
private async void CheckProgressbar()
{
while (CopyCount != FilesCount)
{
await Task.Run(() => { Thread.Sleep(100); });
await CreateBackupProgress.ProgressTo(CopyCount / FilesCount, 100, Easing.Linear);
}
await CreateBackupProgress.ProgressTo(1, 100, Easing.Linear);
}
Upvotes: 3