2014-12-03 104 views
1

我正嘗試在上傳到FTP服務器之前使用GZipStream壓縮文檔。如果在上傳之前將壓縮文件流保存到磁盤,則本地文件系統上的副本是正確的。但是,當我嘗試在FTP服務器上解壓縮文件時,出現7zip中的'File is broken'錯誤。由此產生的解壓縮文件是正確的,直到字符序列重複時的最後幾個字符。我嘗試了許多不同的配置無濟於事。FTP + GZipStream =解壓縮文件時'文件已損壞'

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

回答

2

你不關閉(因此沖洗)的zip流,直到你上傳後。我懷疑這可能是問題所在。移動此行using聲明創建/使用/關閉GZipStream

FTPPut(ftpPutPath, outStream.ToArray()); 

...並獲得完全擺脫Seek通話。 ToArray不需要它,並且代碼中沒有合適的位置來調用它。 (如果在刷新並關閉GZipStream之前調用它,它將修正數據;如果以後調用它,則會在MemoryStream關閉時失敗。)順便說一下,如果需要倒回一個流,我建議使用stream.Position = 0;作爲一個更簡單的選擇。

+0

謝謝喬恩。將outStream.ToArray()移出使用塊之外的技巧。你不需要尋求也是正確的。這是從我傳輸流到FTP而不是字節的剩餘時間。我建議一個小的編輯,因爲它不是查找是否應該被刪除,但它必須被刪除,否則會拋出一個封閉的流異常。 – Derpy 2014-12-04 16:29:31

+0

@TobinChee:謝謝 - 我已經編輯了相應的答案。 – 2014-12-04 17:28:41