客戶端文件下載
public class DownloadTools
{
/// <summary>
/// 下載實體
/// </summary>
private WebClient client;
/// <summary>
/// 文件存儲路徑
/// </summary>
private string tempFilePath;
/// <summary>
/// 下載文件的臨時文件名
/// </summary>
private string tempFileName;
/// <summary>
/// 下載進度條
/// </summary>
private ProgressBar pbDownload;
/// <summary>
/// 下載百分比
/// </summary>
private Label lbDownload;
/// <summary>
/// 構造函數
/// </summary>
public DownloadTools(ProgressBar pbDownload,Label lbDownload)
{
this.pbDownload = pbDownload;
this.lbDownload = lbDownload;
client = new WebClient();
client.DownloadFileCompleted += Client_DownloadFileCompleted;
client.DownloadProgressChanged += Client_DownloadProgressChanged;
}
/// <summary>
/// 異步下載
/// </summary>
/// <param name="serverPath">服務地址</param>
/// <param name="webHeaderCollection">請求頭部信息</param>
public void DownloadFileAsync(string serverPath)
{
FolderBrowserDialog folder = new FolderBrowserDialog();
folder.Description = "選擇文件存放目錄";
if (folder.ShowDialog() == DialogResult.OK)
{
tempFilePath = folder.SelectedPath;
if (!Directory.Exists(tempFilePath))
{
MessageBox.Show(tempFilePath + " 文件路徑或部分路徑不存在");
return;
}
Uri serverUri = new Uri(serverPath);
tempFileName = Guid.NewGuid().ToString() + ".temp";
//下載路徑必須包含路徑和文件名
string filePath = Path.Combine(tempFilePath, tempFileName);
//client.Headers = webHeaderCollection;
client.DownloadFileAsync(serverUri, filePath);
}
}
/// <summary>
/// 文件下載進度顯示
/// </summary>
private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
var responseHeaders = client.ResponseHeaders;
int totalLength;
if (responseHeaders != null)
{
bool isParseOk = int.TryParse(responseHeaders["ContentLength"], out totalLength);
if (isParseOk)
{
int Value = (int)e.BytesReceived;
pbDownload.Minimum = 0;
pbDownload.Maximum = totalLength;
pbDownload.Value = Value;
lbDownload.Text = totalLength == 0 ? "%" : ((int)(100.0 * Value / totalLength)).ToString() + "%";
}
}
}
/// <summary>
/// 下載完成後,刪除臨時文件,賦予服務器上的文件名
/// </summary>
private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
var responseHeaders = client.ResponseHeaders;
string downloadFileName = HttpUtility.UrlDecode(responseHeaders["ContentFileName"]);
if (responseHeaders["ContentError"] != null)
{
string error = HttpUtility.UrlDecode(responseHeaders["ContentError"]);
MessageBox.Show(error);
File.Delete(Path.Combine(tempFilePath, tempFileName));
}
else
{
if (e.Error != null)
{
if (e.Error.InnerException != null)
{
MessageBox.Show(e.Error.InnerException.Message);
}
else
{
MessageBox.Show(e.Error.Message);
}
}
else
{
//替換文件名字
string sourcePath = Path.Combine(tempFilePath, tempFileName);
string destPath = Path.Combine(tempFilePath, downloadFileName);
destPath = JudgeIsExist(destPath);
File.Move(sourcePath, destPath);
File.Delete(Path.Combine(tempFilePath, tempFileName));
}
}
}
/// <summary>
/// 避免文件重複
/// </summary>
private string JudgeIsExist(string path)
{
if (File.Exists(path))
{
string extension = Path.GetExtension(path);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
path = Path.Combine(tempFilePath, fileNameWithoutExtension + "-副本" + extension);
return JudgeIsExist(path);
}
else
{
return path;
}
}
}
客戶端文件上傳
public class UploadTools
{
/// <summary>
/// 下載實體
/// </summary>
private WebClient client;
/// <summary>
/// 上傳進度條
/// </summary>
private ProgressBar pbUpload;
/// <summary>
/// 上傳百分比
/// </summary>
private Label lbUpload;
/// <summary>
/// 構造函數
/// </summary>
public UploadTools(ProgressBar pbUpload, Label lbUpload)
{
this.pbUpload = pbUpload;
this.lbUpload = lbUpload;
client = new WebClient();
client.UploadProgressChanged += Client_UploadProgressChanged;
client.UploadFileCompleted += Client_UploadFileCompleted;
}
/// <summary>
/// 異步上傳
/// </summary>
/// <param name="serverPath">服務地址</param>
/// <param name="webHeaderCollection">請求頭</param>
public void UploadFileAsync(string serverPath)
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Multiselect = false;
if (fileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = fileDialog.FileName;
if (!string.IsNullOrEmpty(filePath))
{
//擴展名
string extension = Path.GetExtension(filePath);
//文件名
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
//帶擴展名的文件名
string fileName = Path.GetFileName(filePath);
//client.Headers = webHeaderCollection;
client.UploadFileAsync(new Uri(serverPath), filePath);
}
}
}
/// <summary>
/// 上傳完畢
/// </summary>
private void Client_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
{
var responseHeaders = client.ResponseHeaders;
if (responseHeaders != null && responseHeaders["ContentError"] != null)
{
string error = HttpUtility.UrlDecode(responseHeaders["ContentError"]);
MessageBox.Show(error);
}
else
{
if (e.Error != null)
{
if (e.Error.InnerException != null)
{
MessageBox.Show(e.Error.InnerException.Message);
}
else
{
MessageBox.Show(e.Error.Message);
}
}
}
}
/// <summary>
/// 上傳進度
/// </summary>
private void Client_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
pbUpload.Minimum = 0;
pbUpload.Maximum = (int)e.TotalBytesToSend;
pbUpload.Value = (int)e.BytesSent;
lbUpload.Text = e.ProgressPercentage.ToString();
}
}
調用例子
/// <summary>
/// 上傳文件
/// </summary>
private void BtnUpload_Click(object sender, EventArgs e)
{
//構造請求頭信息
//WebHeaderCollection webHeaderCollection = new WebHeaderCollection();
//webHeaderCollection.Add("FunctionType", "ModelFileRelated");
//webHeaderCollection.Add("RequestType", "Upload");
//webHeaderCollection.Add("ProjectId", "");
//webHeaderCollection.Add("FileType", HttpUtility.UrlEncode(""));
//webHeaderCollection.Add("FileRemarks", HttpUtility.UrlEncode(""));
//webHeaderCollection.Add("ModelId", "");
string allParams = "?FunctionType=Upload";
allParams += "&";
allParams += "&FileType=" + HttpUtility.UrlEncode("");
allParams += "&FileRemarks=" + HttpUtility.UrlEncode("");
allParams += "&ModelId=";
new UploadTools(pbUpload, lbUpload).UploadFileAsync("ModelFileUploadAndDownload.ashx" + allParams);
}
/// <summary>
/// 點擊文件下載
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnDownload_Click(object sender, EventArgs e)
{
//構造請求頭信息
//WebHeaderCollection webHeaderCollection = new WebHeaderCollection();
//webHeaderCollection.Add("FunctionType", "");
//webHeaderCollection.Add("RequestType", "");
//webHeaderCollection.Add("FileGuid", "");
string allParams = "?FunctionType=Download";
allParams += "&";
new DownloadTools(pbDownload,lbDownload).DownloadFileAsync("ModelFileUploadAndDownload.ashx" + allParams);
}
服務端IHttpHandler
public class ModelFileDownload : IHttpHandler
{
/// <summary>
/// 數據庫實體
/// </summary>
private FileImageEntities fileInfoSqlServer = new FileImageEntities();
/// <summary>
/// 文件存儲目錄
/// </summary>
private string fileSaveDirectory = ConfigurationManager.AppSettings["modelFileSavePath"];
public void ProcessRequest(HttpContext context)
{
NameValueCollection allParams = context.Request.Params;
string functionType = allParams["FunctionType"];
if (!string.IsNullOrEmpty(functionType))
{
if (functionType.Equals("Upload"))
{
//如果上傳文件
SaveFileFromClient(context);
}
else if (functionType.Equals("Download"))
{
//如果下載文件
PrepareForResponse(context);
}
}
}
public bool IsReusable
{
get
{
return false;
}
}
/// <summary>
/// 響應前數據準備
/// </summary>
/// <param name="guid"></param>
private void PrepareForResponse(HttpContext context)
{
string fileGuid = context.Request.Params["FileGuid"];
if (!string.IsNullOrEmpty(fileGuid))
{
//查詢數據庫中存儲的文件路徑
var fileInfo //文件存儲信息
if (fileInfo != null && fileInfo.FilePath != null && fileInfo.FileName != null && fileInfo.FileExtension != null)
{
ResponseFile(@fileInfo.FilePath, fileInfo.FileName + fileInfo.FileExtension);
}
else
{
ErrorResponse("文件不存在");
}
}
else
{
ErrorResponse("文件不存在");
}
}
/// <summary>
/// 根據文件路徑下載指定文件
/// </summary>
public void ResponseFile(string filepath, string filename)
{
Stream iStream = null;
byte[] buffer = new Byte[1024 * 10];
int length;
long dataToRead;
if (System.IO.File.Exists(filepath))
{
iStream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
dataToRead = iStream.Length;
HttpContext.Current.Response.ContentType = "application/octet-stream";//直接用鏈接再網頁上下載
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(filename));
//自定義字段
HttpContext.Current.Response.AddHeader("ContentFileName", HttpUtility.UrlEncode(filename));
HttpContext.Current.Response.AppendHeader("ContentLength", dataToRead.ToString());
while (dataToRead > 0)
{
if (HttpContext.Current.Response.IsClientConnected)
{
length = iStream.Read(buffer, 0, buffer.Length);
HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);
HttpContext.Current.Response.Flush();
dataToRead = dataToRead - length;
}
else
{
dataToRead = -1;
}
}
if (iStream != null) iStream.Close();
HttpContext.Current.Response.End();
}
else
{
ErrorResponse("文件不存在");
}
}
/// <summary>
/// 保存文件到服務器
/// </summary>
public void SaveFileFromClient(HttpContext context)
{
NameValueCollection allParams = context.Request.Params;
string projectId = allParams["ProjectId"];
string modelId = allParams["ModelId"];
string fileType = HttpUtility.UrlDecode(allParams["FileType"]);
string fileRemarks = allParams["FileRemarks"] == null ? null : HttpUtility.UrlDecode(allParams["FileRemarks"]);
string dateTime = DateTime.Now.ToString("yy-MM-dd");
HttpFileCollection files = context.Request.Files;
if (files != null && files.Count > 0)
{
#region 文件存儲路徑
string fileNameWithExtension = files[0].FileName;
string fileNameWithOutExtension = Path.GetFileNameWithoutExtension(fileNameWithExtension);
string extension = Path.GetExtension(fileNameWithExtension);
string newFileSaveAbsolutePath = fileSaveDirectory + @"\" + dateTime;
if (!Directory.Exists(newFileSaveAbsolutePath))
{
Directory.CreateDirectory(newFileSaveAbsolutePath);
}
//判斷文件路徑是否已存在
string fileGuid = JudgeIsExist(newFileSaveAbsolutePath, extension);
string fileSaveAbsolutePath = Path.Combine(newFileSaveAbsolutePath, fileGuid + extension);
#endregion
files[0].SaveAs(fileSaveAbsolutePath);//存儲文件
}
}
/// <summary>
/// 錯誤返回 ContentError
/// </summary>
private static void ErrorResponse(string error)
{
HttpContext.Current.Response.AddHeader("ContentError", HttpUtility.UrlEncode(error));
HttpContext.Current.Response.End();
}
/// <summary>
/// 判斷文件存儲路徑是否已存在
/// </summary>
/// <returns>fileGuid</returns>
private string JudgeIsExist(string newFileSaveAbsolutePath,string extension)
{
string fileGuid = Guid.NewGuid().ToString();
string fileSaveAbsolutePath = Path.Combine(newFileSaveAbsolutePath, fileGuid + extension);
if (!System.IO.File.Exists(fileSaveAbsolutePath))
{
return fileGuid;
}
else
{
return JudgeIsExist(newFileSaveAbsolutePath, extension);
}
}
}