zhouli 发表于 2015-11-6 11:14:20

大文件上传之FTP文件上传

  我想很多人都知道.net自带的上传控件是不支持大文件上传的,默认情况下是4M,当然你可以通过配置WEB.CONFIG来增大上传大小,但是会影响服务器的性能.
  这里就大文件上传提供一个解决方案,就是采用FTP上传,FTP协议是支持大文件上传的.再大的都吃得消.因此,我们的目的就是再服务器上配置好FTP服务器.然后上传文件就交给FTP服务器来完成.可以手动在DOS中操作FTP服务器.也可以用代码来操作,下面是一个代码的例子,摘录自MSDN:
  FTPState.cs:
using System;
using System.Data;
using System.Configuration;
using System.Threading;
using System.Net;

/**//// <summary>
/// FTPState 的摘要说明
/// </summary>
public class FTPState
...{
    private ManualResetEvent wait;

    private FtpWebRequest request;

    private string fileName;

    private Exception operationException = null;

    string status;
   
    public FTPState()
    ...{
      wait = new ManualResetEvent(false);
    }

    public ManualResetEvent OperationComplete
    ...{
      get ...{ return wait; }
    }

    public FtpWebRequest Request
    ...{
      get
      ...{
            return request;
      }
      set
      ...{
            request = value;
      }
    }
    public string FileName
    ...{
      get ...{ return fileName; }
      set ...{ fileName = value; }
    }

    public Exception OperationException
    ...{
      get ...{ return operationException; }
      set ...{ operationException = value; }
    }

    public string StateDescription
    ...{
      get ...{ return status; }
      set ...{ status = value; }
    }
}
FTPsupport.cs:using System;
using System.Data;
using System.Configuration;

using System.Net;
using System.IO;
using System.Threading;

/**//// <summary>
/// FTPsupport 的摘要说明
/// </summary>
public class FTPsupport
...{
    public FTPsupport()
    ...{
      //
      // TODO: 在此处添加构造函数逻辑
      //
    }
    public static bool ListFilesOnServer(Uri serverUri,ref string message,ref Stream responseStream)
    ...{
      // The serverUri should start with the ftp:// scheme.
      if (serverUri.Scheme != Uri.UriSchemeFtp)
      ...{
            return false;
      }
      // Get the object used to communicate with the server.
      FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
      request.Method = WebRequestMethods.Ftp.ListDirectory;

      // Get the ServicePoint object used for this request, and limit it to one connection.
      // In a real-world application you might use the default number of connections (2),
      // or select a value that works best for your application.

      ServicePoint sp = request.ServicePoint;
      //Console.WriteLine(&quot;ServicePoint connections = {0}.&quot;, sp.ConnectionLimit);
      sp.ConnectionLimit = 1;

      FtpWebResponse response = (FtpWebResponse)request.GetResponse();
      //Stream responseStream = null;
      // The following streams are used to read the data returned from the server.
      StreamReader readStream = null;
      try
      ...{
            responseStream = response.GetResponseStream();
            readStream = new StreamReader(responseStream, System.Text.Encoding.UTF8);

            if (readStream != null)
            ...{
                // Display the data received from the server.
                //Console.WriteLine(readStream.ReadToEnd());
                message = readStream.ReadToEnd();
            }
            //Console.WriteLine(&quot;List status: {0}&quot;, response.StatusDescription);
      }
      finally
      ...{
            //if (readStream != null)
            //{
            //    readStream.Close();
            //}
            if (response != null)
            ...{
                response.Close();
            }
      }

      return true;
    }
    public static bool DelFile(Uri serverUri,ref string result)
    ...{
      if(serverUri.Scheme!=Uri.UriSchemeFtp)
      ...{
            return false;
      }
      FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
      
      request.Method = WebRequestMethods.Ftp.DeleteFile;

      FtpWebResponse response = (FtpWebResponse)request.GetResponse();

      result = response.StatusDescription;

      response.Close();

      return true;
    }
    public static bool FileDownload1(Uri serverUri,ref string content,ref Stream filestream)
    ...{
      if(serverUri.Scheme!=Uri.UriSchemeFtp)
      ...{
            return false;
      }
      FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);

      request.Method = WebRequestMethods.Ftp.DownloadFile;

      FtpWebResponse response = (FtpWebResponse)request.GetResponse();

      filestream = response.GetResponseStream();

      StreamReader reader = new StreamReader(filestream, System.Text.Encoding.UTF8);

      content = reader.ReadToEnd();

      response.Close();

      return true;
    }
    public static bool FileDownload(Uri serverUri,ref string filestring)
    ...{
      if (serverUri.Scheme != Uri.UriSchemeFtp)
      ...{
            return false;
      }

      WebClient request = new WebClient();

      request.Credentials = new NetworkCredential(&quot;anonymous&quot;, &quot;xiao_jun_0820@163.com&quot;);

      try
      ...{
            byte[] newFileData = request.DownloadData(serverUri);

            //这里ref回去的是下载的文件的内容,然后在前台新建一个同类型的文件,把内容写进去就OK了.
            filestring = System.Text.Encoding.UTF8.GetString(newFileData);//这个地方可能会有点问题,如果你要下载的文件不是UTF-8形式保存的,则文件内容中的中文将变乱码,那就只能预先将FTP服务器上的文件保存为UTF-8形式.
      }
      catch(WebException e)
      ...{
            filestring = e.ToString();
      }
      return true;
    }

    public static bool FileUpLoad(string fileName,Uri serverUri)
    ...{
      ManualResetEvent waitObject;

      FTPState state = new FTPState();

      FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
      request.Method = WebRequestMethods.Ftp.UploadFile;
      request.Credentials = new NetworkCredential(&quot;anonymous&quot;, &quot;xiao_jun_0820@163.com&quot;);

      state.FileName = fileName;
      state.Request = request;

      waitObject=state.OperationComplete;

      state.Request.BeginGetRequestStream(new AsyncCallback(EndGetStreamCallback),state);

      waitObject.WaitOne();

      if (state.OperationException != null)
      ...{
            throw state.OperationException;
            return false;

      }
      else
      ...{
            return true;
      }


    }

    private static void EndGetStreamCallback(IAsyncResult ar)
    ...{
      FTPState state = (FTPState)ar.AsyncState;

      Stream requestStream;

      try
      ...{
            requestStream = state.Request.EndGetRequestStream(ar);

            const int buffLength = 2048;
            byte[] buffer = new byte;
            int count = 0;
            int readBytes = 0;
            FileStream stream = File.OpenRead(state.FileName);
            do
            ...{
                readBytes = stream.Read(buffer, 0, buffLength);
                requestStream.Write(buffer, 0, readBytes);
                count += readBytes;
            }
            while (readBytes != 0);
            //发送请求之前关闭该请求流
            requestStream.Close();

            state.Request.BeginGetResponse(new AsyncCallback(EndGetResponseCallback), state);
      }
      catch (Exception e)
      ...{
            state.OperationException = e;
            state.OperationComplete.Set();
            return;
      }

    }

    private static void EndGetResponseCallback(IAsyncResult ar)
    ...{
      FTPState state = (FTPState)ar.AsyncState;

      FtpWebResponse response = null;

      try
      ...{
            response = (FtpWebResponse)state.Request.EndGetResponse(ar);
            response.Close();
            state.StateDescription = response.StatusDescription;
            state.OperationComplete.Set();
      }
      catch (Exception e)
      ...{
            state.OperationException = e;
            state.OperationComplete.Set();
      }

    }
}
这两个类我稍微做了点点修改,原文请查看MSDN.             版权声明:本文为博主原创文章,未经博主允许不得转载。
页: [1]
查看完整版本: 大文件上传之FTP文件上传