大文件上传之FTP文件上传

来源:互联网 发布:量化投资用什么软件 编辑:程序博客网 时间:2024/06/05 17:55

 我想很多人都知道.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("ServicePoint connections = {0}.", 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("List status: {0}", 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("anonymous""xiao_jun_0820@163.com");

        
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("anonymous""xiao_jun_0820@163.com");

        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[buffLength];
            
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.