c# 文件的断点续传
标签:drop mode image format emd pen obj 客户端 split
一、开篇描述
本篇博客所描述的断点续传功能是基于c#语言,服务器端采用.net mvc框架,客户端采用winform框架。
本篇博客实现断点续传功能的基本思路:1)服务器端是把接收到的文件流,追加到已有的文件;2)客户端是把文件流截段上传;
其实,任何一种计算机语言基于这个思路,都可以实现断点续传的功能。
二、服务器端
namespace MvcApp.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
//string ip = Request.UserHostAddress;
//string port = Request.ServerVariables["REMOTE_PORT"].ToString();
return View();
}
///
/// 获取续传点。
///
///
///
public string GetFileResumePoint(string md5Name)
{
var saveFilePath = Server.MapPath("~/Images/") + md5Name;
if (System.IO.File.Exists(saveFilePath))
{
var fs = System.IO.File.OpenWrite(saveFilePath);
var fsLength = fs.Length.ToString();
fs.Close();
return fsLength;
}
return "0";
}
///
/// 文件续传。
///
///
[HttpPost]
public HttpResponseMessage FileResume()
{
var fileStream = Request.InputStream;
var md5Name = Request.QueryString["md5Name"];
SaveAs(Server.MapPath("~/Images/") + md5Name, fileStream);
return new HttpResponseMessage(HttpStatusCode.OK);
}
///
/// 给已有文件追加文件流。
///
///
///
private void SaveAs(string saveFilePath, System.IO.Stream stream)
{
//接收到的字节信息。
long startPosition = 0;
long endPosition = 0;
var contentRange = Request.Headers["Content-Range"];//contentRange样例:bytes 10000-20000/59999
if (!string.IsNullOrEmpty(contentRange))
{
contentRange = contentRange.Replace("bytes", "").Trim();
contentRange = contentRange.Substring(0, contentRange.IndexOf("/"));
string[] ranges = contentRange.Split(‘-‘);
startPosition = long.Parse(ranges[0]);
endPosition = long.Parse(ranges[1]);
}
//默认写针位置。
System.IO.FileStream fs;
long writeStartPosition = 0;
if (System.IO.File.Exists(saveFilePath))
{
fs = System.IO.File.OpenWrite(saveFilePath);
writeStartPosition = fs.Length;
}
else
{
fs = new System.IO.FileStream(saveFilePath, System.IO.FileMode.Create);
}
//调整写针位置。
if (writeStartPosition > endPosition)
{
fs.Close();
return;
}
else if (writeStartPosition startPosition && writeStartPosition 0)
{
fs.Write(nbytes, 0, nReadSize);
nReadSize = stream.Read(nbytes, 0, 512);
}
fs.Close();
}
}
}
三、客户端
1 界面如下:
2 代码如下:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
///
/// 定义委托。
///
///
delegate void ChangeText(string text);
///
/// 暂停标记。
///
int flag = 0;
///
/// 上传的文件路径。
///
string filePath;
///
/// 上传的文件md5值。
///
string md5Str;
///
/// 上传的文件续传点。
///
long startPoint;
public Form1()
{
InitializeComponent();
}
///
/// 委托方法。
///
///
public void ChangeLabelText(string text)
{
this.label1.Text = text;
}
///
/// 得到文件的MD5值。
///
///
///
public string GetFileMd5(string filePath)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
Byte[] hashBytes = md5.ComputeHash(fs);
fs.Close();
return BitConverter.ToString(hashBytes).Replace("-", "");
}
///
/// 得到文件的续传点。
///
///
///
///
public long GetFileResumePoint(string md5Str, string fileExtension)
{
System.Net.WebClient webClient = new System.Net.WebClient();
string urlStr = "http://file.taiji.com/Home/GetFileResumePoint?md5Name=" + md5Str + fileExtension;
byte[] infoBytes = webClient.DownloadData(urlStr);
string result = System.Text.Encoding.UTF8.GetString(infoBytes);
if (string.IsNullOrEmpty(result))
{
return 0;
}
return Convert.ToInt64(result);
}
public void ResumeFileThread()
{
MessageBox.Show(ResumeFile("http://file.taiji.com/Home/FileResume", filePath, startPoint, 1024 * 128, md5Str));
}
public string ResumeFile(string hostUrl, string filePath, long startPoint, int byteCount, string md5Str)
{
string result = "上传成功!";
byte[] data;
System.Net.WebClient webClient = new System.Net.WebClient();
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
long fileLength = fs.Length;
BinaryReader bReader = new BinaryReader(fs);
try
{
#region 续传处理
if (startPoint == fileLength)
{
result = "文件秒传!";
}
if (startPoint >= 1 && startPoint fileLength)
{
data = new byte[Convert.ToInt32(fileLength - startPoint)];
bReader.Read(data, 0, Convert.ToInt32(fileLength - startPoint));
step = Convert.ToInt32(fileLength - startPoint);
}
else
{
data = new byte[byteCount];
bReader.Read(data, 0, byteCount);
step = byteCount;
}
webClient.Headers.Remove(HttpRequestHeader.ContentRange);
webClient.Headers.Add(HttpRequestHeader.ContentRange, "bytes " + startPoint + "-" + (startPoint + step) + "/" + fs.Length);
webClient.UploadData(hostUrl + "?md5Name=" + md5Str + Path.GetExtension(filePath), "POST", data);
this.BeginInvoke(new ChangeText(ChangeLabelText), (startPoint + step) + "/" + fileLength);
pause:
if (flag == 1)
{
Thread.Sleep(1000);
goto pause;
}
}
#endregion
}
catch (Exception ex)
{
result = ex.Message;
}
bReader.Close();
fs.Close();
return result;
}
///
/// 上传按钮点击事件。
///
///
///
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
filePath = openFileDialog.FileName;
md5Str = GetFileMd5(filePath);
startPoint = GetFileResumePoint(md5Str, Path.GetExtension(filePath));
ThreadStart ts = new ThreadStart(ResumeFileThread);
Thread t = new Thread(ts);
t.Start();
}
}
///
/// 暂停按钮点击事件。
///
///
///
private void button2_Click(object sender, EventArgs e)
{
flag = 1;
}
///
/// 继续按钮点击事件。
///
///
///
private void button3_Click(object sender, EventArgs e)
{
flag = 0;
}
///
/// 允许拖拽。
///
///
///
private void Form1_Load(object sender, EventArgs e)
{
this.AllowDrop = true;
}
///
/// 拖拽上传。
///
///
///
private void Form1_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];
MessageBox.Show("准备上传" + files.Length + "个文件!");
foreach (string file in files)
{
MessageBox.Show("开始上传文件:" + file);
filePath = file;
md5Str = GetFileMd5(filePath);
startPoint = GetFileResumePoint(md5Str, Path.GetExtension(filePath));
ThreadStart ts = new ThreadStart(ResumeFileThread);
Thread t = new Thread(ts);
t.Start();
}
}
}
}
}
c# 文件的断点续传
标签:drop mode image format emd pen obj 客户端 split
原文地址:http://www.cnblogs.com/by-lhc/p/7794350.html
文章来自:
搜素材网的
编程语言模块,转载请注明文章出处。
文章标题:
c# 文件的断点续传
文章链接:http://soscw.com/index.php/essay/80693.html
评论