Zip-файл, созданный с SharpZipLib, не может быть открыт на Mac OS X

Один определенный экземпляр, где я использую friend, при создании Singleton классы. friend ключевое слово позволяет мне создать функцию средства доступа, которая более кратка, чем всегда наличие "GetInstance ()" метод на классе.

/////////////////////////
// Header file
class MySingleton
{
private:
    // Private c-tor for Singleton pattern
    MySingleton() {}

    friend MySingleton& GetMySingleton();
}

// Accessor function - less verbose than having a "GetInstance()"
//   static function on the class
MySingleton& GetMySingleton();


/////////////////////////
// Implementation file
MySingleton& GetMySingleton()
{
    static MySingleton theInstance;
    return theInstance;
}

13
задан Peter Mortensen 23 February 2010 в 10:54
поделиться

3 ответа

Итак, я поискал еще несколько примеров использования SharpZipLib и, наконец, заставил его работать в Windows и os x. В основном я добавил "Crc32" файла в zip-архив. Не знаю, что это такое.

Вот код, который у меня сработал:

        using (var outStream = new FileStream("Out3.zip", FileMode.Create))
        {
            using (var zipStream = new ZipOutputStream(outStream))
            {
                Crc32 crc = new Crc32();

                foreach (string pathname in pathnames)
                {
                    byte[] buffer = File.ReadAllBytes(pathname);

                    ZipEntry entry = new ZipEntry(Path.GetFileName(pathname));
                    entry.DateTime = now;
                    entry.Size = buffer.Length;

                    crc.Reset();
                    crc.Update(buffer);

                    entry.Crc = crc.Value;

                    zipStream.PutNextEntry(entry);
                    zipStream.Write(buffer, 0, buffer.Length);
                }

                zipStream.Finish();

                // I dont think this is required at all
                zipStream.Flush();
                zipStream.Close();

            }
        }

Объяснение от cheeso:

CRC - это циклическая проверка избыточности - это контрольная сумма входных данных. Обычно заголовок для каждой записи в zip-файле содержит набор метаданных, включая некоторые вещи, которые не могут быть известны, пока все данные записи не будут переданы в потоковом режиме - CRC, размер несжатого и сжатый. При генерации zip-файла через потоковый вывод спецификация zip позволяет установить бит (бит 3), чтобы указать, что эти три поля данных будут сразу же следовать за данными ввода.

Если вы используете ZipOutputStream, обычно при записи входных данных он сжимается, вычисляется CRC, и 3 поля данных записываются сразу после данных файла.

Вы дважды передали данные в потоковом режиме - в первый раз неявно, когда вы вычисляете CRC файла перед его записью. Если моя теория верна, то происходит следующее: когда вы предоставляете CRC в zipStream перед записью данных файла, это позволяет CRC появляться в своем обычном месте в заголовке записи, что делает OSX счастливой. Я не уверен, что происходит с двумя другими величинами (сжатый и несжатый размер).


13
ответ дан 1 December 2019 в 17:42
поделиться

Я не знаю наверняка, потому что я не очень хорошо знаком ни с SharpZipLib, ни с OSX, но у меня все же может быть для вас кое-что полезное.

Я потратил некоторое время на изучение спецификации zip, и на самом деле я написал DotNetZip , zip-библиотеку для .NET, не имеющую отношения к SharpZipLib.

В настоящее время на пользовательских форумах по DotNetZip обсуждают zip-файлы, созданные DotNetZip, которые нельзя прочитать в OSX. У одного из людей, использующих библиотеку, возникла проблема, похожая на то, что вы видите. Только я понятия не имею, что такое файл .cpgxz.

Мы его немного выследили. На данный момент наиболее многообещающей теорией является то, что OSX не любит «бит 3» в «битовом поле общего назначения» в заголовке каждой записи zip.

Бит 3 не нов. PKWare добавила бит 3 в спецификацию 17 лет назад. Он был предназначен для поддержки потокового создания архивов таким же образом, как работает SharpZipLib. DotNetZip также имеет способ создавать zip-файл по мере его потоковой передачи, и он также установит бит-3 в zip-файле, если используется таким образом, хотя обычно DotNetZip создает zip-файл с неустановленным бит-3 в этом.

Насколько мы можем судить, когда установлен бит 3, программа чтения zip-файлов OSX (что бы это ни было - как я уже сказал, я не знаком с OSX) подавляет zip-файл. То же содержимое zip-архива, созданное без бита 3, позволяет открывать zip-файл. На самом деле это не так просто, как просто перевернуть один бит - наличие бита сигнализирует о наличии других метаданных. Поэтому я использую «бит 3» как сокращение для всего этого.

Теоретически проблема связана с битом 3. Я не Я сам это тестировал. Произошло некоторое несоответствие импеданса связи с человеком, у которого есть машина OSX, так что это пока не решено.

Но если эта теория верна, это объяснит вашу ситуацию: WinRar и любая машина с Windows могут открыть файл, а OSX - нет.

На форумах DotNetZip мы обсуждали, что делать с этой проблемой. Насколько я могу судить, считыватель почтового индекса OSX неисправен и не может обрабатывать бит 3, поэтому обходной путь - создать zip-файл с неустановленным битом 3. Я не знаю, можно ли убедить SharpZipLib сделать это.

Я знаю, что если вы используете DotNetZip, и используете обычный класс ZipFile, и сохраняете в поток, доступный для поиска (например, файл файловой системы), вы получите zip-архив, в котором не установлен бит 3. Если теория верна, он должен открываться без проблем на Mac каждый раз. Это результат, о котором сообщил пользователь DotNetZip. Это всего лишь один результат, который пока нельзя обобщать, но он выглядит правдоподобным.

пример кода для вашего сценария:

  using (ZipFile zip = new ZipFile()
  {
      zip.AddFiles(pathnames);
      zip.Save("Out2.zip");
  }

Для любопытных: в DotNetZip вы получите установленный бит 3, если вы используете класс ZipFile и сохраните его в поток без поиска (например, Response.OutputStream ASPNET) или если вы используете Класс ZipOutputStream в DotNetZip, который всегда записывает только вперед (без обратного поиска). Я думаю, что ZipOutputStream SharpZipLib также всегда «только вперед».

16
ответ дан 1 December 2019 в 17:42
поделиться

Что происходит с файлом .cpgz , так это то, что утилита архивирования запускается с помощью файла с расширением .zip . Утилита архивирования проверяет файл и считает, что он не сжат, поэтому сжимает его. По какой-то странной причине по умолчанию используется .cpgz (архивирование CPIO + сжатие gzip). Вы можете установить другое значение по умолчанию в настройках утилиты архивирования.

Если вы действительно обнаружите, что это проблема с zip-декодером OS X, сообщите об ошибке . Вы также можете попробовать использовать инструмент командной строки ditto , чтобы распаковать его; вы можете получить лучшее сообщение об ошибке. Конечно, OS X также включает unzip , утилиту Info-ZIP, но я ожидал, что это сработает.

1
ответ дан 1 December 2019 в 17:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: