Skip to content

CopyToAsync fails with ZipOutputStream #167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 of 8 tasks
vector-man opened this issue Feb 24, 2017 · 4 comments
Closed
1 of 8 tasks

CopyToAsync fails with ZipOutputStream #167

vector-man opened this issue Feb 24, 2017 · 4 comments

Comments

@vector-man
Copy link

vector-man commented Feb 24, 2017

Steps to reproduce

An exception occurs when adding a file if using CopyToAsync

I'm using Windows 10 x64.

    private const int BufferSize = 4096;

    private async Task CompressFolderAsync(string path, ZipOutputStream zipStream, int folderOffset, CancellationToken cancellationToken)
    {
        string[] files = Directory.GetFiles(path);

        foreach (string filename in files)
        {
            cancellationToken.ThrowIfCancellationRequested();

            FileInfo fi = new FileInfo(filename);

            string entryName = filename.Substring(folderOffset); // Makes the name in zip based on the folder
            entryName = ZipEntry.CleanName(entryName); // Removes drive from name and fixes slash direction
            ZipEntry newEntry = new ZipEntry(entryName);
            newEntry.DateTime = fi.LastWriteTime; // Note the zip format stores 2 second granularity

            // Specifying the AESKeySize triggers AES encryption. Allowable values are 0 (off), 128 or 256.
            // A password on the ZipOutputStream is required if using AES.
            //   newEntry.AESKeySize = 256;

            // To permit the zip to be unpacked by built-in extractor in WinXP and Server2003, WinZip 8, Java, and other older code,
            // you need to do one of the following: Specify UseZip64.Off, or set the Size.
            // If the file may be bigger than 4GB, or you do not need WinXP built-in compatibility, you do not need either,
            // but the zip will be in Zip64 format which not all utilities can understand.
            //   zipStream.UseZip64 = UseZip64.Off;
            newEntry.Size = fi.Length;

            zipStream.PutNextEntry(newEntry);

            // Zip the file.
            // the "using" will close the stream even if an exception occurs
            using (FileStream streamReader = File.OpenRead(filename))
            {
                await streamReader.CopyToAsync(zipStream, BufferSize); // <- This throws an exception.
               // If I use streamReader.CopyTo(zipStream, BufferSize), no error occurs. 
            }
            zipStream.CloseEntry();
        }
        string[] folders = Directory.GetDirectories(path);
        foreach (string folder in folders)
        {
            await CompressFolderAsync(folder, zipStream, folderOffset, cancellationToken);
        }
    }

Expected behavior

The file should be copied without error.

Actual behavior

I get System.NotSupportedException with this message: Size was 0, but I expected y"

Version of SharpZipLib

0.86.0

Obtained from (place an x between the brackets for all that apply)

  • Compiled from source
  • branch: _______
  • commit: _______
  • Downloaded DLL from GitHub
  • Downloaded DLL from SourceForge
  • Downloaded DLL from _______
  • DLL included as part of
  • Package installed using:
  • NuGet
  • MyGet
  • Chocolatey
@piksel
Copy link
Member

piksel commented Sep 16, 2018

Yes, writing to ZipOutputStream using async does not work and since it is CPU-bound, there should be no real point in doing so.
Closing this a duplicate of #223.

@piksel piksel closed this as completed Sep 16, 2018
@andrensairr
Copy link

I'm not convinced there is no use case for this. CoptyToAsync is part of the API for the base Stream class, and as such should agnostic of the Stream implementation; there is nothing to say that output will be CPU-bound. It could be, but if the ZipOutputStream is backed by a FileStream then in all likelihood it will be IO bound.

@piksel
Copy link
Member

piksel commented Mar 4, 2019

Well, if we were to rewrite it to support async consumer streams it might not be CPU-bound, true. But I closed it because it's a duplicate, not because it's not possible. It would require a bigger rewrite though.

@Numpsy
Copy link
Contributor

Numpsy commented Mar 5, 2019

fwiw, I tried running the sample above with the latest code and didn't see any exceptions - not sure if it's been fixed by other changes or just only happens in some circumstances though?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants