2009-07-20 94 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); 
} 

有关这方面的一个好处是,它也将只使用固定的内存量,而不是整个文件读入内存一次。