FTP + GZipStream = 解压缩时“文件已损坏”
本文关键字:文件 已损坏 文件已损坏 GZipStream 解压缩 FTP | 更新日期: 2023-09-27 18:33:05
我正在尝试使用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>' -->
在上传 zip 流之前,您不会关闭(因此刷新)压缩流。我怀疑这很可能是问题所在。将此行移到创建/使用/关闭GZipStream
的 using
语句之后:
FTPPut(ftpPutPath, outStream.ToArray());
。并完全摆脱Seek
电话。 ToArray
不需要它,并且代码中没有合适的点来调用它。(如果在刷新并关闭GZipStream
之前调用它,它将对应数据;如果之后调用它,它将在关闭MemoryStream
时失败。顺便说一句,当您确实需要倒带流时,我建议您使用 stream.Position = 0;
作为更简单的替代方案。