Я пытаюсь использовать 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>' -->
Вы не закрываете (и, следовательно, очищаете) поток zip до тех пор, пока вы его не загрузите. Я подозреваю, что это может быть проблемой. Переместите эту строку после инструкции using
которая создает/использует/закрывает GZipStream
:
FTPPut(ftpPutPath, outStream.ToArray());
... и полностью избавиться от вызова Seek
. ToArray
не требует этого, и в вашем коде нет подходящей точки для его вызова. (Если вы GZipStream
его перед тем, как GZipStream
и закроете GZipStream
, он будет корректировать данные, а если вы его вызове потом, то он будет терпеть неудачу, так как MemoryStream
будет закрыт.) В стороне, когда вам нужно перемотать поток, d рекомендуем использовать stream.Position = 0;
как более простая альтернатива.