2009-07-20 79 views
3

我有這樣的方法來傳輸使用FTP服務器的文件:C#中的FTP返回損壞的文件,爲什麼?

private void TransferNeededFiles(IEnumerable<string> filenames) 
{ 
    foreach (var filename in filenames) 
    { 
     var request = WebRequest.Create(new Uri(@"ftp://{0}/{1}".Fill(Config.ServerUri, filename))) as FtpWebRequest; 

     if (request != null) 
     { 
      request.Credentials = new NetworkCredential(Config.Username, Config.Password); 

      request.Method = WebRequestMethods.Ftp.DownloadFile; 
      using (var streamReader = new StreamReader(request.GetResponse().GetResponseStream())) 
      { 
       var fileStream = new FileStream(@"{0}/{1}".Fill(Config.DestinationFolderPath, filename), FileMode.Create); 

       var writer = new StreamWriter(fileStream); 
       writer.Write(streamReader.ReadToEnd()); 
       writer.Flush(); 
       writer.Close(); 

       fileStream.Close(); 
      } 
     } 
    } 
} 

加上.gz文件,包含在文件名列表,總是損壞。當我嘗試使用Windows資源管理器從FTP進行復制時,該文件未被損壞。你知道發生了什麼嗎?

+0

你確定你使用的是二進制傳輸而不是ascii? – 2009-07-20 21:27:32

+0

我使用上面的這段代碼。我沒有指定ascii或binary,這可能是問題嗎? – 2009-07-20 21:29:57

+0

查看UseBinary http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.usebinary.aspx。 – 2009-07-20 21:36:26

回答

7

問題是這樣的線:

writer.Write(streamReader.ReadToEnd()); 

StreamReader.ReadToEnd()返回一個Unicode編碼的字符串。你想要一些能夠讀取字節流字節的東西。

+0

我認爲喬爾的釘釘(像往常一樣)。您可能也想同時讀取數據流,而不是一次全部讀取。 – 2009-07-20 21:36:53

3

Reader s和Writer使用Unicode字符。要傳輸想要使用原始字節的二進制數據,所以您應該使用普通的Stream s。您可以從一個流複製到另一個類似下面的循環:

BufferedStream inputStream, outputStream; 
byte[] buffer = new byte[4096]; 
int bytesRead; 

while ((bytesRead = inputStream.Read(buffer)) > 0) 
{ 
    outputStream.Write(buffer, 0, bytesRead); 
} 

有關這方面的一個好處是,它也將只使用固定的內存量,而不是整個文件讀入內存一次。