0

I am using DotNetZip's GZipStream to zip a file. The problem I have is that the resulting file is empty. I tried flushing/closing streams, but without result. Anyone knows what I do wrong:

using (var outputStream = new FileStream(path + fileName + ".gz", FileMode.Create, FileAccess.Write, FileShare.None))
{
    using (var zipStream = new GZipStream(outputStream, CompressionMode.Compress))
    {
        using (var inputStream = new FileStream(path + fileName, FileMode.Open, FileAccess.Read, FileShare.None))
        {
            await inputStream.CopyToAsync(zipStream);
        }
    }
}
Kees
  • 1,408
  • 1
  • 15
  • 27
  • Are you sure you're using `await` correctly? Try the synchronous `CopyTo` instead. – Luaan Jul 25 '17 at 08:07
  • I just tried that, but with the same result – Kees Jul 25 '17 at 08:09
  • 2
    Unrelated to the question, but: you should really use `Path.Combine` to build composite paths, not concatenation – Marc Gravell Jul 25 '17 at 08:09
  • Are you `await`-ing the thing that surrounds this? It is possible that what you're seeing is simply a timing bug due to not `await`-ing completion – Marc Gravell Jul 25 '17 at 08:13
  • Why are you using DotNetZip? `GZipStream` is an inbuilt .NET class... btw: for the code shown in my answer, I tested with both `System.IO.Compression.GZipStream` and `Ionic.Zlib.GZipStream` - they behave identically – Marc Gravell Jul 25 '17 at 08:13
  • @MarcGravell Because the DotNetZip GZipStream is more efficient. Its better in performance and delivers smaller files. – Kees Jul 25 '17 at 08:15
  • @KeesdeWit k; just change `System.IO.Compression` to `Ionic.Zlib` in the `using` directives in my answer, and it works the same; the size is unchanged – Marc Gravell Jul 25 '17 at 08:15

1 Answers1

1

Works fine here; do you have a fully reproducible example, perhaps based on this one?

Results:

dummy.txt:6492 bytes
Waiting for completion (don't do this in real code, ever)...
Complete
dummy.txt.gz:512 bytes

Code:

using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;

static class P
{
    static void Main()
    {

        File.WriteAllLines("dummy.txt",
            Enumerable.Range(1, 200).Select(i => "this is some contents: line " + i));

        WriteSize("dummy.txt");

        var t = Task.Run(() => DoTheThing(Environment.CurrentDirectory + "\\", "dummy.txt"));
        Console.WriteLine("Waiting for completion (don't do this in real code, ever)...");
        t.Wait();
        Console.WriteLine("Complete");
        WriteSize("dummy.txt.gz");
    }

    private static void WriteSize(string path)
    {
        var file = new FileInfo(path);
        Console.WriteLine(path + ":" + file.Length + " bytes");
    }

    async static Task DoTheThing(string path, string fileName)
    {
        using (var outputStream = new FileStream(path + fileName + ".gz", FileMode.Create, FileAccess.Write, FileShare.None))
        {
            using (var zipStream = new GZipStream(outputStream, CompressionMode.Compress))
            {
                using (var inputStream = new FileStream(path + fileName, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    await inputStream.CopyToAsync(zipStream);
                }
            }
        }
    }
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • The "DoTheThing" method is exactly as I have it. Gives me an emtpy file – Kees Jul 25 '17 at 08:14
  • Does the **exact code shown** give you an empty file? also, if you add debug info to the start and end of `DoTheThing`, *does it complete*? Possibilities: a) it is throwing an exception that you are swallowing (action: add some error handling that lets you see if this is the case); b) you are using a sync-context that is blocked, perhaps a code-induced deadlock (action: look at the code that *invokes* the method and how it is waited/awaited) – Marc Gravell Jul 25 '17 at 08:19
  • 1
    It did work fine. Another process was causing the file to be recreated – Kees Jul 25 '17 at 08:19