C# 文件上传 实时回调 显示进度条 (HttpWebRequest方法)
简介
实时显示上传进度,参数可以根据自己需要来进行修改,可以封装为单独的上传函数
代码分为四个部分:上传部分、调用部分、实时进度部分、上传完成部分
核心代码
/// <summary>
/// 将本地文件上传到指定的服务器(HttpWebRequest方法)
/// </summary>
/// <param name="url"></param>
/// <param name="values"></param>
/// <param name="filePath"></param>
/// <param name="progress"></param>
/// <param name="completed"></param>
public static void UploadFile(string url, NameValueCollection values, string filePath, Action<string, int> progress, Action<string> completed)
{
var fileStream = File.OpenRead(filePath);
var fileName = Path.GetFileName(filePath);
var ms = new MemoryStream();
// Make a copy of the input stream in case sb uses disposable stream
fileStream.CopyTo(ms);
// Stream position needs to be set to zero - just to be sure.
ms.Position = 0;
try
{
const string contentType = "application/octet-stream";
var request = WebRequest.Create(url);
request.Method = "POST";
request.Headers.Add("Authorization", GlobalConfig.token);
request.Headers.Add("source", "pc");
var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo);
request.ContentType = "multipart/form-data; boundary=" + boundary;
boundary = "--" + boundary;
var dataStream = new MemoryStream();
byte[] buffer;
// Write the values
foreach (string name in values.Keys)
{
buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
dataStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.ASCII.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"{1}{1}", name, Environment.NewLine));
dataStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.UTF8.GetBytes(values[name] + Environment.NewLine);
dataStream.Write(buffer, 0, buffer.Length);
}
// Write the file
buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
dataStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.UTF8.GetBytes($"Content-Disposition: form-data; name=\"file\"; filename=\"{fileName}\"{Environment.NewLine}");
dataStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.ASCII.GetBytes(string.Format("Content-Type: {0}{1}{1}", contentType, Environment.NewLine));
dataStream.Write(buffer, 0, buffer.Length);
ms.CopyTo(dataStream);
buffer = Encoding.ASCII.GetBytes(Environment.NewLine);
dataStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.ASCII.GetBytes(boundary + "--");
dataStream.Write(buffer, 0, buffer.Length);
dataStream.Position = 0;
// Important part: set content length to directly write to network socket
request.ContentLength = dataStream.Length;
var requestStream = request.GetRequestStream();
// Write data in chunks and report progress
var size = dataStream.Length;
const int chunkSize = 64 * 1024;
buffer = new byte[chunkSize];
long bytesSent = 0;
int readBytes;
while ((readBytes = dataStream.Read(buffer, 0, buffer.Length)) > 0)
{
requestStream.Write(buffer, 0, readBytes);
bytesSent += readBytes;
var status = "Uploading... " + bytesSent / 1024 + "KB of " + size / 1024 + "KB";
var percentage = Convert.ToInt32(100 * bytesSent / size);
progress(status, percentage);
}
// Get response from host
using (var response = request.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var stream = new MemoryStream())
{
responseStream.CopyTo(stream);
var result = Encoding.UTF8.GetString(stream.ToArray());
//completed(result == string.Empty
// ? "failed:" + result
// : "ok:" + result);
completed(result);
}
}
catch (Exception e)
{
throw e;
}
}
调用
FrmUtil.UploadFile(
url: url,
filePath: path,
values: new NameValueCollection(),
progress: (status, percent) => UploadProgress(status, percent),
completed: UploadCompleted
);
回调
可实时实时进度显示
/// <summary>
/// 上传进度
/// </summary>
/// <param name="status"></param>
/// <param name="percent"></param>
private void UploadProgress(string status, int percent)
{
lab_upload.Text = percent + "%";
}
上传完成
/// <summary>
/// 上传完成
/// </summary>
/// <param name="response"></param>
private void UploadCompleted(string response)
{
var apiRes = JsonConvert.DeserializeObject<ApiResultEntity<List<string>>>(response);
var apiRet = apiRes.ToReturn();
if (apiRet.res)
{
var url = apiRet.Data[0];
// 发送socket
var u = UserEntity.userInfo;
string recImUserID = friendData.userId.ToString();
string fileName = skinPictureBox3.Tag.ToString().GetFileName();
string size = skinPictureBox3.Tag.ToString().GetFileSize() + "MB";
FriendSendSocket.SendFriendFileMsg(
u.name,
u.imUserId,
u.imgPath,
recImUserID,
new MsgFileEntity()
{
fileName = fileName,
size = size,
url = url
}, UserEntity.userInfo.name, UserEntity.userInfo.imgPath);
}
else
{
MessageBox.Show($"发送失败:{apiRet.msg}");
}
lab_upload.Visible = false;
lab_upload.Text = "00.00%";
}