GZipStream complains that the magic number in the header is wrong

I am trying to use data from the National Weather Service (USA), but something changed recently and the GZip file no longer opens.

.NET 4.5 complains that ...

Message=The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.
Source=System
StackTrace:
   at System.IO.Compression.GZipDecoder.ReadHeader(InputBuffer input)
   at System.IO.Compression.Inflater.Decode()
   at System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length)
   at System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count)

      

I don't understand what has changed, but it becomes a real show stopper. Can anyone with experience using GZip tell me what has changed to make this stop work?

File that works:

http://www.srh.noaa.gov/ridge2/Precip/qpehourlyshape/2015/201504/20150404/nws_precip_2015040420.tar.gz

The file that doesn't work:

http://www.srh.noaa.gov/ridge2/Precip/qpehourlyshape/2015/201505/20150505/nws_precip_2015050505.tar.gz

Update with sample code

const string url = "http://www.srh.noaa.gov/ridge2/Precip/qpehourlyshape/2015/201505/20150505/nws_precip_2015050505.tar.gz";
string appPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string downloadPath = Path.Combine(appPath, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "nws_precip_2015050505.tar.gz");
using (var wc = new WebClient())
{
    wc.DownloadFile(url, downloadPath);
}

string extractDirPath = Path.Combine(appPath, "Extracted");
if (!Directory.Exists(extractDirPath))
{
    Directory.CreateDirectory(extractDirPath);
}
string extractFilePath = Path.Combine(extractDirPath, "nws_precip_2015050505.tar");

using (var fsIn = new FileStream(downloadPath, FileMode.Open, FileAccess.Read))
using (var fsOut = new FileStream(extractFilePath, FileMode.Create, FileAccess.Write))
using (var gz = new GZipStream(fsIn, CompressionMode.Decompress, true))
{
    gz.CopyTo(fsOut);
}

      

+3


source to share


2 answers


It looks like this SOMETIMES service is returning format files tar

disguised as .tar.gz

. This is very confusing, but if you check that the first two bytes are: 0x1F

and 0x8B

, you can determine if the file is a GZip by checking its magic numbers manually.



using (FileStream fs = new FileStream(downloadPath, FileMode.Open, FileAccess.Read))
{
    byte[] buffer = new byte[2];
    fs.Read(buffer, 0, buffer.Length);
    if (buffer[0] == 0x1F
        && buffer[1] == 0x8B)
    {
        // It probably a GZip file
    }
    else
    {
        // It probably not a GZip file
    }
}

      

+1


source


[Allowed] GZipStream complains that the magic number in the header is incorrect

// Exception magic number tar.gz file

Migcal error error

  • The file doesn't compress in tar.gz correctly
  • The file size is too large, over 1 + GB


Decision on it

  • use .net framework 4.5.1 for this exception // OR //

  • create exsiting app without changing .net framework. Follow the step for implementation.

    • Remane abc.tar.gz as abc (remove extension).

    • pass this file and direct name to compress function

* public static void Compress (DirectoryInfoSelected directory, string directoryPath)

    {
        foreach (FileInfo fileToCompress in directorySelected.GetFiles())
        {
            using (FileStream originalFileStream = fileToCompress.OpenRead())
            {
                if ((File.GetAttributes(fileToCompress.FullName) &
                   FileAttributes.Hidden) != FileAttributes.Hidden & fileToCompress.Extension != ".tar.gz")
                {
                    using (FileStream compressedFileStream = File.Create(fileToCompress.FullName + ".tar.gz"))
                    {
                        using (System.IO.Compression.GZipStream compressionStream = new System.IO.Compression.GZipStream(compressedFileStream,
                           System.IO.Compression.CompressionMode.Compress))
                        {
                            originalFileStream.CopyTo(compressionStream);
                        }
                    }
                    FileInfo info = new FileInfo(directoryPath + "\\" + fileToCompress.Name + ".tar.gz");
                }
            }
        }
    }


3. implement this code in following exception handler try catch block
    try
    {
        TarGzFilePath=@"c:\temp\abc.tar.gz";
        FileStream streams = File.OpenRead(TarGzFilePath);
        string FileName=string.Empty;
        GZipInputStream tarGz = new GZipInputStream(streams);
        TarInputStream tar = new TarInputStream(tarGz);
        // exception will occured in below lines should apply try catch

        TarEntry ze;
            try
            {
                ze = tar.GetNextEntry();// exception occured here "magical number"
            }
            catch (Exception extra)
            {
                tar.Close();
                tarGz.Close();
                streams.Close();
                //please close all above , other wise it will come with exception "tihs process use by another process"
                //rename your file *for better accuracy you can copy file to other location 

                File.Move(@"c:\temp\abc.tar.gz", @"c:\temp\abc"); // rename file 
                DirectoryInfo directorySelected = new DirectoryInfo(Path.GetDirectoryName(@"c:\temp\abc"));
                Compress(directorySelected, directoryPath); // directorySelected=c:\temp\abc , directoryPath=c:\temp\abc.tar.gz // process in step 2 function 
                streams = File.OpenRead(TarGzFilePath);
                tarGz = new GZipInputStream(streams);
                tar = new TarInputStream(tarGz);
                ze = tar.GetNextEntry();                    
            }
            // do anything with extraction with your code
    }
    catch (exception ex)
    {
        tar.Close();
        tarGz.Close();
        streams.Close();
    }

      

-3


source







All Articles