如何实现SharpZipLib.Portable所需的VirtualFileSystem?

时间:2015-07-06 14:28:56

标签: c# xamarin.forms portable-class-library sharpziplib

我想将SharpZipLib.Portable库添加到我的Xamarin.Forms PCL项目中。我的目标是Android和iOS。该文档提到您必须实现VirtualFileSystem才能使用该库,但我不知道该怎么做,而且我无法找到有关此主题的更多信息。

是否有人使用此库可以指导我使用它所需的步骤?

2 个答案:

答案 0 :(得分:12)

我在尝试实施SharpZipLib.Portable时最终到了这里。 我开始在没有IVirtualFileSystem的情况下使用它,因为我已经知道了一个名为(PCLStorage)的库,它知道如何在文件系统中读写(在iOSAndroid上测试)

注意:此实施都在针对iOSAndroid的PCL中。不需要Android或iOS的特定代码。

以下是如何使用PCLStorageSharpZipLib.Portable提取Zip文件的简单示例:

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

如果您想了解一些如何使用SharpZipLib.Portable的示例,请点击此处(原SharpZipLib): Code referenceZip samples

<强> ALTERNATIVE:

在完成我上面解释的内容之后,我得到了一个更简单的解决方案,因为我只需要支持ZIP文件。 我使用了ZipArchive ClassSystem.IO.Compression中的PCLStorage,因此使用此解决方案我没有使用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(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);
                }
            }
        }
    }                    
}

答案 1 :(得分:0)

这对我有用:

  1. 仅安装PCL项目的SharpZipLib.Portable

  2. 使用它的代码:

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