C# IHttpHandler文件传输进度?
我有一个用于分块文件传输的简单IHttpHandler,在客户端代码中,我想报告文件百分比的进度,过去我是通过将传输的字节数除以以字节为单位的文件大小来完成的,然后在达到每10%时生成一个事件,我知道这不是最好的方法。不管怎么说,我都提取了所有的代码,但是在我下面使用的方法中有更好的方法吗C# IHttpHandler文件传输进度?,c#,c#-4.0,ihttphandler,C#,C# 4.0,Ihttphandler,我有一个用于分块文件传输的简单IHttpHandler,在客户端代码中,我想报告文件百分比的进度,过去我是通过将传输的字节数除以以字节为单位的文件大小来完成的,然后在达到每10%时生成一个事件,我知道这不是最好的方法。不管怎么说,我都提取了所有的代码,但是在我下面使用的方法中有更好的方法吗 //IHTTPMethod //Open file string file = System.IO.Path.GetFileName(pub
//IHTTPMethod
//Open file
string file = System.IO.Path.GetFileName(pubAttFullPath.ToString());
FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
//Chunk size that will be sent to Server
int chunkSize = 49152;
// Unique file name
string fileName = Guid.NewGuid() + Path.GetExtension(file);
int totalChunks = (int)Math.Ceiling((double)fileStream.Length / chunkSize);
// Loop through the whole stream and send it chunk by chunk;
for (int i = 0; i < totalChunks; i++)
{
int startIndex = i * chunkSize;
int endIndex = (int)(startIndex + chunkSize > fileStream.Length ? fileStream.Length : startIndex + chunkSize);
int length = endIndex - startIndex;
byte[] bytes = new byte[length];
fileStream.Read(bytes, 0, bytes.Length);
//Request url, Method=post Length and data.
string requestURL = "http://localhost:16935/Transfer.ashx";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestURL);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
// Chunk(buffer) is converted to Base64 string that will be convert to Bytes on the handler.
string requestParameters = @"fileName=" + fileName + @"&secretKey=mySecret" +
"&data=" + HttpUtility.UrlEncode(Convert.ToBase64String(bytes));
// finally whole request will be converted to bytes that will be transferred to HttpHandler
byte[] byteData = Encoding.UTF8.GetBytes(requestParameters);
request.ContentLength = byteData.Length;
Stream writer = request.GetRequestStream();
writer.Write(byteData, 0, byteData.Length);
writer.Close();
// here we will receive the response from HttpHandler
StreamReader stIn = new StreamReader(request.GetResponse().GetResponseStream());
string strResponse = stIn.ReadToEnd();
stIn.Close();
}
//IHTTPMethod
//打开文件
string file=System.IO.Path.GetFileName(pubAttFullPath.ToString());
FileStream FileStream=新FileStream(文件,FileMode.Open,FileAccess.Read);
//将发送到服务器的块大小
int chunkSize=49152;
//唯一文件名
字符串文件名=Guid.NewGuid()+Path.GetExtension(文件);
int totalChunks=(int)Math.天花((double)fileStream.Length/chunkSize);
//在整个流中循环并逐块发送;
for(int i=0;ifileStream.Length?fileStream.Length:startIndex+chunkSize);
int length=endIndex-startIndex;
字节[]字节=新字节[长度];
读取(字节,0,字节,长度);
//请求url,方法=帖子长度和数据。
字符串requestURL=”http://localhost:16935/Transfer.ashx";
HttpWebRequest request=(HttpWebRequest)WebRequest.Create(requestURL);
request.Method=“POST”;
request.ContentType=“application/x-www-form-urlencoded”;
//区块(缓冲区)转换为Base64字符串,该字符串将在处理程序上转换为字节。
字符串requestParameters=@“fileName=“+fileName+@”&secretKey=mySecret”+
“&data=“+HttpUtility.UrlEncode(Convert.ToBase64String(字节));
//最后,整个请求将转换为字节,并传输到HttpHandler
byte[]byteData=Encoding.UTF8.GetBytes(请求参数);
request.ContentLength=byteData.Length;
流编写器=request.GetRequestStream();
writer.Write(byteData,0,byteData.Length);
writer.Close();
//在这里,我们将收到来自HttpHandler的响应
StreamReader stIn=新的StreamReader(request.GetResponse().GetResponseStream());
字符串strResponse=stIn.ReadToEnd();
stIn.Close();
}
我的服务器端代码在这里:这可能是报告进度的最好地方,因为我可以在这里本地更新到SQL
public class IHTTPTransfer : IHttpHandler
{
/// <summary>
/// You will need to configure this handler in the web.config file of your
/// web and register it with IIS before being able to use it. For more information
/// see the following link: http://go.microsoft.com/?linkid=8101007
/// </summary>
#region IHttpHandler Members
public bool IsReusable
{
// Return false in case your Managed Handler cannot be reused for another request.
// Usually this would be false in case you have some state information preserved per request.
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
string accessCode = context.Request.Params["secretKey"].ToString();
if (accessCode == "mySecret")
{
string fileName = context.Request.Params["fileName"].ToString();
byte[] buffer = Convert.FromBase64String(context.Request.Form["data"]);
SaveFile(fileName, buffer);
}
}
public void SaveFile(string fileName, byte[] buffer)
{
string Path = @"C:\Filestorage\" + fileName;
FileStream writer = new FileStream(Path, File.Exists(Path) ? FileMode.Append : FileMode.Create, FileAccess.Write);
writer.Write(buffer, 0, buffer.Length);
writer.Close();
}
#endregion
}
公共类IHTTPTransfer:IHttpHandler
{
///
///您需要在服务器的web.config文件中配置此处理程序
///在能够使用它之前,请访问web并向IIS注册。有关详细信息,请参阅
///请参阅以下链接:http://go.microsoft.com/?linkid=8101007
///
#区域IHttpHandler成员
公共布尔可重用
{
//如果无法将托管处理程序重新用于其他请求,则返回false。
//通常,如果每个请求都保留了一些状态信息,那么这将是错误的。
获取{return true;}
}
公共void ProcessRequest(HttpContext上下文)
{
字符串accessCode=context.Request.Params[“secretKey”].ToString();
if(accessCode==“mySecret”)
{
字符串文件名=context.Request.Params[“fileName”].ToString();
byte[]buffer=Convert.FromBase64String(context.Request.Form[“data”]);
保存文件(文件名、缓冲区);
}
}
公共void保存文件(字符串文件名,字节[]缓冲区)
{
字符串路径=@“C:\Filestorage\”+文件名;
FileStream writer=newfilestream(路径,File.Exists(路径)?FileMode.Append:FileMode.Create,FileAccess.Write);
writer.Write(buffer,0,buffer.Length);
writer.Close();
}
#端区
}
一旦有了处理程序,您就可以轻松地进行处理。下面是示例代码:
/// <summary>
/// The download file.
/// </summary>
/// <param name="state">
/// The state.
/// </param>
/// <exception cref="InvalidDataException">
/// </exception>
private void DownloadFile()
{
string url = "http://localhost:16935/Transfer.ashx";
bool cancel = false;
string savePath = "C:/Temp";
try
{
// Put the object argument into an int variable
int start = 0;
if (File.Exists(savePath))
{
start = (int)new System.IO.FileInfo(savePath).Length;
}
// Create a request to the file we are downloading
var request = (HttpWebRequest)WebRequest.Create(url);
// Set the starting point of the request
request.AddRange(start);
// Set default authentication for retrieving the file
request.Credentials = CredentialCache.DefaultCredentials;
// Retrieve the response from the server
using (var response = (HttpWebResponse)request.GetResponse())
{
// check file lenght
int fileLength = 0;
int.TryParse(resp.Headers.Get("Content-Length"), out fileLength);
// Open the URL for download
using (Stream responseStream = response.GetResponseStream())
{
// Create a new file stream where we will be saving the data (local drive)
using (var fs = new FileStream(savePath, FileMode.Append, FileAccess.Write, FileShare.Read))
{
// It will store the current number of bytes we retrieved from the server
int bytesSize;
// A buffer for storing and writing the data retrieved from the server
var downBuffer = new byte[2048];
// Loop through the buffer until the buffer is empty
while ((bytesSize = responseStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
var args = new CancelEventArgs(false);
this.OnCancel(args);
if (args.Cancel)
{
cancel = true;
break;
}
// Write the data from the buffer to the local hard drive
fs.Write(downBuffer, 0, bytesSize);
fs.Flush();
float percentComplete = 0;
if (fileLength > 0)
{
percentComplete = (100 * fs.Length) / (float)fileLength;
if (percentComplete > 100)
{
percentComplete = 100;
}
}
this.OnProgressChanged(new ProgressChangedEventArgs((int)percentComplete));
}
}
}
}
}
catch (Exception ex)
{
throw;
}
}
//
///下载文件。
///
///
///国家。
///
///
///
私有void下载文件()
{
字符串url=”http://localhost:16935/Transfer.ashx";
bool cancel=false;
字符串savePath=“C:/Temp”;
尝试
{
//将对象参数放入int变量中
int start=0;
if(File.Exists(保存路径))
{
start=(int)new System.IO.FileInfo(savePath.Length;
}
//创建对我们正在下载的文件的请求
var request=(HttpWebRequest)WebRequest.Create(url);
//设置请求的起始点
请求。添加范围(开始);
//设置检索文件的默认身份验证
request.Credentials=CredentialCache.DefaultCredentials;
//从服务器检索响应
使用(var response=(HttpWebResponse)request.GetResponse())
{
//检查文件长度
int fileLength=0;
int.TryParse(分别为Headers.Get(“内容长度”),out fileLength);
//打开URL进行下载
使用(Stream responseStream=response.GetResponseStream())
{
//创建一个新的文件流,我们将在其中保存数据(本地驱动器)
使用(var fs=newfilestream)(保存路径,Fi
/// <summary>
/// Adds or removes cancel event.
/// </summary>
public event CancelEventHandler Cancel;
/// <summary>
/// Adds or removes progress changed event.
/// </summary>
public event EventHandler<ProgressChangedEventArgs> ProgressChanged;
/// <summary>
/// Raises progress changed event.
/// </summary>
/// <param name="e">
/// <see cref="ProgressChangedEventArgs"/> params.
/// </param>
protected virtual void OnProgressChanged(ProgressChangedEventArgs e)
{
EventHandler<ProgressChangedEventArgs> handler = this.ProgressChanged;
if (handler != null)
{
handler(this, e);
}
}
/// <summary>
/// Raises cancel event.
/// </summary>
/// <param name="e">
/// </param>
protected virtual void OnCancel(CancelEventArgs e)
{
CancelEventHandler handler = this.Cancel;
if (handler != null)
{
handler(this, e);
}
}