FTP + GZipStream = 'Файл поврежден' при распаковке

1

Я пытаюсь использовать GZipStream для сжатия документа перед загрузкой на FTP-сервер. Если я сохраню сжатый поток файлов на диск непосредственно перед загрузкой, копия в локальной файловой системе верна. Однако, когда я пытаюсь разархивировать файл на FTP-сервере, я получаю сообщение "Файл нарушен" из 7zip. Полученный распакованный файл является правильным до тех пор, пока не будет повторяться последовательность символов. Я пробовал много разных конфигураций безрезультатно.

    public static void FTPPut_Compressed(string fileContents, string ftpPutPath)
    {
      using (var inStream = new System.IO.MemoryStream(System.Text.Encoding.Default.GetBytes(fileContents)))
      {
         inStream.Seek(0, SeekOrigin.Begin);
         using (var outStream = new System.IO.MemoryStream())
         {
             using (var zipStream = new GZipStream(outStream, CompressionMode.Compress))
             {
                 inStream.CopyTo(zipStream);
                 outStream.Seek(0, SeekOrigin.Begin);
                 FTPPut(ftpPutPath, outStream.ToArray());
             }
         }
      }
    }

    private static void FTPPut(string ftpPutPath, byte[] fileContents)
    {
      FtpWebRequest request;

      request = WebRequest.Create(new Uri(string.Format(@"ftp://{0}/{1}", Constants.FTPServerAddress, ftpPutPath))) as FtpWebRequest;
      request.Method = WebRequestMethods.Ftp.UploadFile;
      request.UseBinary = true;
      request.UsePassive = true;
      request.KeepAlive = true;
      request.Credentials = new NetworkCredential(Constants.FTPUserName, Constants.FTPPassword);
      request.ContentLength = fileContents.Length;

      using (var requestStream = request.GetRequestStream())
      {
         requestStream.Write(fileContents, 0, fileContents.Length);
         requestStream.Close();
         requestStream.Flush();
      }
    }

Ex поврежденного выхода:

    <?xml version="1.0" encoding="utf-16"?>
        <ArrayOfCreateRMACriteria xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <CreateRMACriteria>
                <RepairOrderId xsi:nil="true" />
                <RMANumber>11-11111</RMANumber>
                <CustomerId>1111</CustomerId>
            </CreateRMACriteria>
        </ArrayOfCreateRMACriteriafriafriafriafriafriafriafriafriafriafriafriafriafriafriafriafriafria
    <!-- missing '></xml>' -->
Теги:
ftp
gzip
gzipstream

1 ответ

2
Лучший ответ

Вы не закрываете (и, следовательно, очищаете) поток zip до тех пор, пока вы его не загрузите. Я подозреваю, что это может быть проблемой. Переместите эту строку после инструкции using которая создает/использует/закрывает GZipStream:

FTPPut(ftpPutPath, outStream.ToArray());

... и полностью избавиться от вызова Seek. ToArray не требует этого, и в вашем коде нет подходящей точки для его вызова. (Если вы GZipStream его перед тем, как GZipStream и закроете GZipStream, он будет корректировать данные, а если вы его вызове потом, то он будет терпеть неудачу, так как MemoryStream будет закрыт.) В стороне, когда вам нужно перемотать поток, d рекомендуем использовать stream.Position = 0; как более простая альтернатива.

  • 0
    Спасибо Джон. Перемещение outStream.ToArray () за пределы блока using добилось цели. Вы также правы, что поиск не нужен. Это было пережитком, когда я передавал потоки на FTP вместо байтов. Я предложил небольшое редактирование, поскольку не нужно удалять запрос, а нужно удалить его, иначе будет выдано исключение закрытого потока.
  • 0
    @TobinChee: Спасибо - я отредактировал ответ соответственно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню