Поврежден zip при передаче потока памяти SharpZipLib в PclStorage

В PCL я использую SharpZipLib.Portable, чтобы заархивировать некоторый контент в MemoryStream, а затем записываю MemoryStream в файл Zip с помощью средства двоичной записи PCLStorage. Однако созданный zip-файл поврежден. При перечислении его содержимого я получаю сообщение:

Архив: zippedfile.zip
предупреждение [zippedfile.zip]: 20 дополнительных байтов в начале или внутри zip-файла
(пытаясь обработать в любом случае)
ошибка [zippedfile.zip]: начало центрального каталога не найдено;
Zip-файл поврежден.
(убедитесь, что вы перенесли или создали zip-файл в
соответствующий режим BINARY и что вы правильно скомпилировали UnZip)

Код ниже. Кто-нибудь может подсказать, где я иду не так? Я не представляю на мгновение, что-то не так с SharpZipLib или PCLStorage, однако есть странная аномалия:

[Редактировать: Некоторый новый свет на аномалию, описанную ниже: Каждое вхождение байта больше 7F транслируется в тройку байтов EF BF BD, что, по-видимому, является многобайтовым представлением UTF8 разновидности символа вопросительного знака. Таким образом, похоже, что PCLStorage рассматривает поток как UTF8. Тогда возникает вопрос, как убедить PCLStorage сделать двоичную передачу. ]

При передаче потока в PCLStorage я проверяю поток в точке останова (переменная 'verify') и вижу, что шестнадцатеричное содержимое правдоподобно похоже на формат ZIP, например, с правильным заголовком ZIP:

50 4B 03 04 14 00 00 00 08 00 45 89 52 48 DF 36... (122 байта)

Когда я затем смотрю на созданный zip-файл в шестнадцатеричном редакторе, я также вижу что-то похожее на формат ZIP, но в теле файла оно отличается!:

50 4B 03 04 14 00 00 00 08 00 45 EF BF BD 52 48... (142 байта)

В обоих случаях эквивалент ASCII имеет форму:

PK....... ABCD.txt.... PK..... ABCD.txt..... PK.....

Аналогичные результаты при использовании кода с fileHandler.WriteAsync вместо.CopyTo.

Другие люди используют двоичную передачу PCLStorage, поэтому я сомневаюсь, что проблема в этом. Что мне не хватает? Любые предложения приветствуются.

Это в Xamarin Forms PCL.

// using ICSharpCode.SharpZipLib.Zip;   // SharpZipLib.Portable
// using PCLStorage;

string content = "ABCD\r\n";            // Desired content of zipped file
byte[] contentBytes = Encoding.UTF8.GetBytes ( content );

using ( MemoryStream contentStream = new MemoryStream () ) 
{
    await contentStream.WriteAsync ( contentBytes, 0, contentBytes.Length );
    contentStream.Position = 0;

    using ( MemoryStream zipStream = new MemoryStream () ) 
    {
        using ( ZipOutputStream s = new ZipOutputStream ( zipStream ) ) 
        {
            s.UseZip64 = UseZip64.Off;
            s.SetLevel (6);             // Compression level

            //Add the text file
            ZipEntry csvEntry = new ZipEntry ( "ABCD.txt" );
            s.PutNextEntry ( csvEntry );
            await contentStream.CopyToAsync (s);
            s.CloseEntry ();

            s.IsStreamOwner = false;    // Do not close zipStream when finishing
            await s.FlushAsync ();      // Write to zipStream
            s.Finish ();
        }

        // Save file to local file system   
        IFolder rootfolder = FileSystem.Current.LocalStorage;
        IFolder exportfolder = await rootfolder.CreateFolderAsync ( "Exports", CreationCollisionOption.OpenIfExists );
        IFolder subfolder = await exportfolder.CreateFolderAsync ( "Zips", CreationCollisionOption.OpenIfExists );
        IFile file = await subfolder.CreateFileAsync ( "ZippedFile.zip", CreationCollisionOption.ReplaceExisting );
        using (Stream fileHandler = await file.OpenAsync ( FileAccess.ReadAndWrite ) ) 
        {
            zipStream.Position = 0;
            await zipStream.CopyToAsync ( fileHandler );

            // As a sanity check, view the contents of fileHandler
            using ( MemoryStream memStream = new MemoryStream () ) 
            {
                fileHandler.Position = 0;
                fileHandler.CopyTo ( memStream );
                byte[] verify = memStream.ToArray ();
            }   // Put breakpoint here to view contents of verify
        }
    }

1 ответ

Простите, ребята. Виноват! Написанный код работает правильно и создает правильный файл ZIP в файловой системе. Мой тестовый код был проблемой.

-- Билл.

Другие вопросы по тегам