How do I implement the VirtualFileSystem required by SharpZipLib.Portable?
Asked Answered
B

2

11

I would like to add the SharpZipLib.Portable library to my Xamarin.Forms PCL project. I am targeting Android and iOS. The documentation mentions that you must implement a VirtualFileSystem in order to use the library, but I do not know how to do that and I have been unable to find much information on this topic.

Has anyone used this library that can guide me in the steps required to use it?

Battleship answered 6/7, 2015 at 14:28 Comment(0)
A
13

I ended up here when trying to implement the SharpZipLib.Portable. I start using it without the IVirtualFileSystem because i had already a library called (PCLStorage) that knows how to read and write in filesystem (tested it on iOS and Android).

NOTE: This implementations are all inside a PCL targeting iOS, Android. No specific code for Android or iOS are needed.

Here is a simple example how to extract a Zip file using PCLStorage and SharpZipLib.Portable:

public async void DonwLoadAndStoreZipFile()
{
    var bytes = await DownloadImageAsync("https://github.com/fluidicon.png");

    // IFolder interface comes from PCLStorage    
    IFolder rootFolder = FileSystem.Current.LocalStorage;
    IFolder folder = await rootFolder.CreateFolderAsync("zipFolder", CreationCollisionOption.OpenIfExists);
    IFile file = await folder.CreateFileAsync("test.zip" , CreationCollisionOption.OpenIfExists);

    using (Stream stream = await file.OpenAsync(FileAccess.ReadAndWrite))
    {
        await stream.WriteAsync(bytes, 0, bytes.Length);
        using (var zf = new ZipFile(stream))
        {
            foreach (ZipEntry zipEntry in zf) 
            {                
                // Gete Entry Stream.
                Stream zipEntryStream = zf.GetInputStream(zipEntry);

                // Create the file in filesystem and copy entry stream to it.
                IFile zipEntryFile = await rootFolder.CreateFileAsync(zipEntry.Name , CreationCollisionOption.FailIfExists);
                using(Stream outPutFileStream = await zipEntryFile.OpenAsync(FileAccess.ReadAndWrite))
                {
                    await zipEntryStream.CopyToAsync(outPutFileStream);
                }
            }
        }
    }                    
}

If you want to get some examples on how to use the SharpZipLib.Portable you can read here (original SharpZipLib): Code reference and Zip samples.

ALTERNATIVE:

After doing what i explained above I ended up with a much simpler solution because i only needed to support ZIP files. I used ZipArchive Class present in System.IO.Compression and PCLStorage, so with this solution i don't used SharpZipLib.Portable.

Here is the version:

public async void DonwLoadAndStoreZipFile()
{
    var bytes = await DownloadImageAsync(https://github.com/fluidicon.png);

    // IFolder interface comes from PCLStorage
    IFolder rootFolder = FileSystem.Current.LocalStorage;
    IFolder folder = await rootFolder.CreateFolderAsync("zipFolder", CreationCollisionOption.OpenIfExists);
    IFile file = await folder.CreateFileAsync("test.zip" , CreationCollisionOption.OpenIfExists);

    using (Stream stream = await file.OpenAsync(FileAccess.ReadAndWrite))
    {
        await stream.WriteAsync(bytes, 0, bytes.Length);
        using(ZipArchive archive = new ZipArchive(stream))
        {
            foreach (ZipArchiveEntry entry in archive.Entries)
            {
                IFile zipEntryFile = await rootFolder.CreateFileAsync(entry.Name, CreationCollisionOption.FailIfExists);
                using (Stream outPutStream = await zipEntryFile.OpenAsync(FileAccess.ReadAndWrite))
                {
                    await entry.Open().CopyToAsync(outPutStream);
                }
            }
        }
    }                    
}
Achorn answered 24/3, 2016 at 9:44 Comment(0)
V
0

This worked for me:

  1. Install SharpZipLib.Portable for PCL project only

  2. Code to use it:

    using ICSharpCode.SharpZipLib.Core;
    using ICSharpCode.SharpZipLib.Zip;
    
    public void ExtractZipFile(string archivePath, string password, string outFolder) {
    
        using(Stream fsInput = File.OpenRead(archivePath)) 
        using(zf = new ZipFile(fs)){
    
        if (!String.IsNullOrEmpty(password)) {
            zf.Password = password;
        }
    
        foreach (ZipEntry zipEntry in zf) {
            if (!zipEntry.IsFile) {
                continue;
            }
            String entryFileName = zipEntry.Name;
    
            var fullZipToPath = Path.Combine(outFolder, entryFileName);
            var directoryName = Path.GetDirectoryName(fullZipToPath);
            if (directoryName.Length > 0) {
                Directory.CreateDirectory(directoryName);
            }
    
            var buffer = new byte[4096];
    
            using(var zipStream = zf.GetInputStream(zipEntry))
            using (Stream fsOutput = File.Create(fullZipToPath)) {
                StreamUtils.Copy(zipStream, fsOutput , buffer);
            }
        }
    }
    }
    
Visayan answered 20/5, 2020 at 23:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.