【问题标题】:FTP + GZipStream = 'File is broken' when unzippedFTP + GZipStream = '文件损坏' 解压时
【发布时间】:2014-12-03 22:47:27
【问题描述】:

我正在尝试使用 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();
      }
    }

损坏输出的例子:

    <?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>' -->

【问题讨论】:

    标签: c# .net ftp gzip gzipstream


    【解决方案1】:

    在您上传压缩流之后之前,您不会关闭(因此刷新)压缩流。我怀疑这很可能是问题所在。将此行移动到创建/使用/关闭GZipStreamusing 语句之后:

    FTPPut(ftpPutPath, outStream.ToArray());
    

    ... 并完全摆脱 Seek 调用。 ToArray 不需要它,并且您的代码中没有合适的点来调用它。 (如果您在刷新并关闭 GZipStream 之前调用它,它会损坏数据;如果您在之后调用它,它将失败,因为 MemoryStream 已关闭。)顺便说一句,当您 do 需要倒带,我建议使用stream.Position = 0; 作为更简单的替代方案。

    【讨论】:

    • 谢谢乔恩。将 outStream.ToArray() 移到 using 块之外就可以了。你也是正确的,不需要寻找。这是我将流而不是字节传递给 FTP 时的残余。我提出了一个小修改,因为它不是是否应该删除搜索,而是必须删除它,否则它会抛出一个关闭的流异常。
    • @TobinChee:谢谢 - 我已经相应地编辑了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多