gz-файл, сгенерированный программно в C #, отличается от сгенерированного вручную - PullRequest
0 голосов
/ 14 сентября 2018

Я делаю анализ filevault, принадлежащего приложению, которое gz-compress и добавляет пользовательский заголовок к каждому загруженному в него файлу.

Заголовок - это ASCII-текст, состоящий из начального элемента заголовка, содержащего контрольную сумму sha-1 сжатого файла и длину распакованного файла до элемента конца заголовка.

Я могу легко распаковать файл вручную, удалив заголовок (обычно около ~ 65 байт), сохранив файл, а затем распаковав его с помощью 7-zip, gunzip и подобных инструментов. Если я проверяю хеш полученного gz-файла и длину распакованного файла, все соответствует ожидаемому хешу и длине, сохраненной в заголовке.

Если я делаю ту же операцию программно, я получаю странные результаты. Я ожидаю, что gz-файл и распакованный файл будут иметь тот же хэш и длину, что и распакованные вручную файлы, но это не так. Файл gz, полученный из приведенного ниже кода, примерно на 700 байт больше, чем файл, обработанный вручную, и, разумеется, хэши не совпадают. Распакованный файл (изображение) визуально идентичен распакованному вручную файлу и имеет точно такую ​​же длину, но дает другое значение хеш-функции.

Открытие двух gz-файлов в 7-zip показывает мне следующее: Manually processed file on the left, programatically processed file on the right.

Левый файл - это gz-файл, который я обработал вручную. Правильный был сделан программно, и утверждает, что (очень то же самое) изображение 2,4 ГБ. Я где-то делаю что-то ужасно неправильно, или это «как задумано»?

    static void Main(string[] args)
{
    string TempDir = @"c:\temp\so\";

    string file = "../../../SampleFiles/SPO_6c5af66f-0a8b-4b27-848b-7e19346ee6c7.jpg";
    FileInfo myFile = new FileInfo(file);

    List<byte> fileContents = new List<byte>();

    using (FileStream fs = myFile.OpenRead())
    {
        int bytesToRead = 1024;
        int fileLength = Convert.ToInt32(fs.Length);

        Byte[] tmpData = new Byte[bytesToRead];

        if (fileLength < bytesToRead) {
            bytesToRead = Convert.ToInt32(fileLength);
        }

        int numRead = fs.Read(tmpData, 0, bytesToRead);

        while (numRead > 0 || fileLength > 0)
        {
            fileContents.AddRange(tmpData);
            numRead = fs.Read(tmpData, 0, bytesToRead);

            fileLength -= bytesToRead;

            if (fileLength < bytesToRead)
            {
                bytesToRead = fileLength;
            }
        }

        var gzdata = fileContents.Skip(66).ToArray<byte>();

        var compressedStream = new MemoryStream(gzdata);
        var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress);
        var resultStream = new MemoryStream();

        zipStream.CopyTo(resultStream);
        var resArray = resultStream.ToArray();

        compressedStream.Flush();

        File.WriteAllBytes(TempDir + "testfile.jpg.gz", gzdata);
        File.WriteAllBytes(TempDir + "testfile.jpg", resultStream.ToArray());

    }
}
...