上傳文件是一個比較常用的功能,前段時間就做了一個上傳圖片的模塊。開始采用的是共享文件夾的方式,後來發現這種方法不太好。於是果斷將其斃掉,後來選擇采用FTP的方式進行上傳。個人感覺FTP的方式還是比較好用的,所以跟大家分享一下。
上傳的核心代碼:
[csharp]
/// <summary>
/// FTP上傳文件
/// </summary>
/// <param name="fileUpload">上傳控件</param>
/// <param name="ftpServerIP">上傳文件服務器IP</param>
/// <param name="ftpUserID">服務器用戶名</param>
/// <param name="ftpPassword">服務器密碼</param>
/// <returns></returns>
public string Upload(FileUpload fileUpload, string ftpServerIP, string ftpUserID, string ftpPassword)
{
string filename = fileUpload.FileName;
string sRet = "上傳成功!";
FileInfo fileInf = new FileInfo(fileUpload.PostedFile.FileName);
string uri = "ftp://" + ftpServerIP + "/" + filename;
FtpWebRequest reqFTP;
// 根據uri創建FtpWebRequest對象
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
// ftp用戶名和密碼
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
// 默認為true,連接不會被關閉
// 在一個命令之後被執行
reqFTP.KeepAlive = false;
// 指定執行什麼命令
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
// 指定數據傳輸類型
reqFTP.UseBinary = true;
reqFTP.UsePassive = false;
// 上傳文件時通知服務器文件的大小
reqFTP.ContentLength = fileInf.Length;
// 緩沖大小設置為2kb
int buffLength = 2048;
byte[] buff = new byte[buffLength];
int contentLen;
// 打開一個文件流 (System.IO.FileStream) 去讀上傳的文件
FileStream fs = fileInf.OpenRead();
try
{
// 把上傳的文件寫入流
Stream strm = reqFTP.GetRequestStream();
// 每次讀文件流的2kb
contentLen = fs.Read(buff, 0, buffLength);
// 流內容沒有結束
while (contentLen != 0)
{
// 把內容從file stream 寫入 upload stream
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
// 關閉兩個流
strm.Close();
fs.Close();
}
catch (Exception ex)
{
sRet = ex.Message;
}
return sRet;
}
/// <summary>
/// FTP上傳文件
/// </summary>
/// <param name="fileUpload">上傳控件</param>
/// <param name="ftpServerIP">上傳文件服務器IP</param>
/// <param name="ftpUserID">服務器用戶名</param>
/// <param name="ftpPassword">服務器密碼</param>
/// <returns></returns>
public string Upload(FileUpload fileUpload, string ftpServerIP, string ftpUserID, string ftpPassword)
{
string filename = fileUpload.FileName;
string sRet = "上傳成功!";
FileInfo fileInf = new FileInfo(fileUpload.PostedFile.FileName);
string uri = "ftp://" + ftpServerIP + "/" + filename;
FtpWebRequest reqFTP;
// 根據uri創建FtpWebRequest對象
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
// ftp用戶名和密碼
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
// 默認為true,連接不會被關閉
// 在一個命令之後被執行
reqFTP.KeepAlive = false;
// 指定執行什麼命令
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
// 指定數據傳輸類型
reqFTP.UseBinary = true;
reqFTP.UsePassive = false;
// 上傳文件時通知服務器文件的大小
reqFTP.ContentLength = fileInf.Length;
// 緩沖大小設置為2kb
int buffLength = 2048;
byte[] buff = new byte[buffLength];
int contentLen;
// 打開一個文件流 (System.IO.FileStream) 去讀上傳的文件
FileStream fs = fileInf.OpenRead();
try
{
// 把上傳的文件寫入流
Stream strm = reqFTP.GetRequestStream();
// 每次讀文件流的2kb
contentLen = fs.Read(buff, 0, buffLength);
// 流內容沒有結束
while (contentLen != 0)
{
// 把內容從file stream 寫入 upload stream
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
// 關閉兩個流
strm.Close();
fs.Close();
}
catch (Exception ex)
{
sRet = ex.Message;
}
return sRet;
}
上面只是一個簡單的上傳,當然上傳之前還需要對文件進行一些驗證,例如文件格式或者文件的大小之類的。簡單驗證請參考上傳圖片之上傳前判斷文件格式與大小。
為了防止重名,可以使用全局唯一標示符GUID,生成一個隨機序列,在理想情況下,任何計算機和計算機集群都不會生成兩個相同的GUID。當然重復的幾率也並不為0,但是非常小了。
[csharp]
/// <summary>
/// 生成全局唯一標示符
/// </summary>
/// <returns></returns>
public string strGUID()
{
string strguid = Guid.NewGuid().ToString();
return strguid;
}
/// <summary>
/// 生成全局唯一標示符
/// </summary>
/// <returns></returns>
public string strGUID()
{
string strguid = Guid.NewGuid().ToString();
return strguid;
}
調用這個方法,然後將返回的序列跟文件名拼接就可以有效的避免文件重名的情況了。當然也可以用系統當前時間來跟文件名進行拼接,這樣或許你感覺更保險一些。具體用那種方法就見仁見智了。