0

我有一种 FTP 下载文件的方法,但我没有在本地保存文件,而是通过 ftp 响应解析内存中的文件。我的问题是,在获取 ftp 响应流后返回流阅读器是一种好习惯吗?因为不想在同一个方法中做解析和其他东西。

var uri = new Uri(string.Format("ftp://{0}/{1}/{2}", "somevalue",     remotefolderpath, remotefilename));
var request = (FtpWebRequest)FtpWebRequest.Create(uri);
request.Credentials = new NetworkCredential(userName, password);

request.Method = WebRequestMethods.Ftp.DownloadFile;

var ftpResponse = (FtpWebResponse)request.GetResponse();
/* Get the FTP Server's Response Stream */
ftpStream = ftpResponse.GetResponseStream();
return responseStream = new StreamReader(ftpStream);
4

3 回答 3

2

对我来说,直接使用流有两个缺点,如果你能忍受它们,你不应该浪费内存或磁盘空间。

  • 在这个流中你不能寻找到一个特定的位置,你只能读取它进来的内容;
  • 您的互联网连接可能会突然断开,并且在解析和处理文件时会出现异常,要么拆分解析和处理,要么确保您的处理例程可以处理文件被第二次处理的情况(在中途失败后第一次尝试)。

要解决这些问题,您可以将流复制到 MemoryStream:

using (var ftpStream = ftpResponse.GetResponseStream())    
{
   var memoryStream = new MemoryStream()
   while ((bytesRead = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
   {
      memoryStream.Write(buffer, 0, bytesRead);
   }  

   memoryStream.Flush();
   memoryStream.Position = 0;
   return memoryStream;                   
}

如果您正在处理较大的文件,我更喜欢将其写入文件,这样可以最大限度地减少应用程序的内存占用:

using (var ftpStream = ftpResponse.GetResponseStream())    
{
   var fileStream = new FileStream(Path.GetTempFileName(), FileMode.CreateNew)
   while ((bytesRead = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
   {
      fileStream.Write(buffer, 0, bytesRead);
   }  

   fileStream.Flush();      
   fileStream.Position = 0;
   return fileStream;
}
于 2013-06-26T09:24:50.263 回答
1

当您执行HttpWebRequest. 如果您正在使用FtpWebRequest它,则意味着您正在处理文件。我会将 responseStream 读取到 byte[] 并返回下载文件的字节文件内容,这样您就可以轻松地使用System.IO.File类来处理文件。

于 2013-06-26T06:05:46.003 回答
0

谢谢卡洛斯这真的很有帮助。我只是返回字节[]

           byte[] buffer = new byte[16 * 1024];

           using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
               memoryStream=ms;
            }
         return memoryStream.ToArray();

并在这样的方法中使用了 byte[]

   public async Task ParseReport(byte[] bytesRead)
    {
        Stream stream = new MemoryStream(bytesRead);
        using (StreamReader reader = new StreamReader(stream))
            {
            string line = null;
            while (null != (line = reader.ReadLine())) 
            {
              string[] values = line.Split(';');
            }
            }
        stream.Close();
    }
于 2013-06-26T09:00:21.180 回答