【问题标题】:Return stream reader from FTP response is good practice or not从 FTP 响应返回流读取器是否是好习惯
【发布时间】:2013-06-26 05:57:11
【问题描述】:

我有一个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);

【问题讨论】:

    标签: c# ftp


    【解决方案1】:

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

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

    要解决这些问题,您可以将流复制到 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;
    }
    

    【讨论】:

    • 似乎有一个错字:while ((bytesRead = ftpStream.Read... 单等号与双等号。
    • bytesRead = 在这里是有意的,这种语法有效(除了缺少;我在上面的行中看到)。测试的布尔值是 (bytesRead ...) > 0
    【解决方案2】:

    当您执行HttpWebRequest 时,我发现返回 responseStream 更为实用。如果您使用FtpWebRequest,则表示您正在处理文件。我会将 responseStream 读取到 byte[] 并返回下载文件的字节文件内容,这样您就可以轻松地使用 System.IO.Fileclasses 来处理文件。

    【讨论】:

      【解决方案3】:

      感谢 Carlos,这真的很有帮助。我只是返回字节[]

                 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();
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-09
        • 2023-02-15
        • 2018-10-20
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多