您的位置:首页 > 理论基础 > 计算机网络

使用HttpWebRequest实现大文件上传(二)

2018-02-04 19:56 447 查看
2、大文件的分片上传

   当一个文件很大时,通过HttpWebRequest上传,一是可能出现内存不足异常(Out
of Memory Exceptions);二是服务器端会出现响应超时。

大文件分片上传,就是把一个大的文件分成若干片,一片一片的传输,避免出现错误。

分片上传范例:



客户端:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp_simple
{
public partial class Form1 : Form
{
long shardSize = 2 * 1024 * 1024;////  //以?MB为一个分片//大于2M <httpRuntime maxRequestLength="20480"/>kb为单位

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Multiselect = true;
fileDialog.Title = "请选择文件";
fileDialog.Filter = "影视图像|*.jpg;*.png;*.gif;*.mp4;*.iso";
if (fileDialog.ShowDialog() == DialogResult.OK)
{
if (fileDialog.FileNames.Length > 0)
{
this.label1.Text = fileDialog.FileNames[0];
}

}
}

private void button2_Click(object sender, EventArgs e)
{
int shardCount; //计数

int errorcount = 0;
int slice_index = 0;
long all_total_size = 0;

string file_name = this.label1.Text;

if (System.IO.File.Exists(file_name) == false)
{
return;
}

var temp_file_info = new FileInfo(file_name);
long size;
size = temp_file_info.Length;                   //总大小
all_total_size += size;            //获取
shardCount = Convert.ToInt32(Math.Ceiling(Convert.ToSingle(size) / Convert.ToSingle(shardSize)));   //总片数
string name;
name = temp_file_info.Name;                   //文件名
progressBar1.Maximum = shardCount;
while (slice_index < shardCount)
{
if (Uploadfile_slice(slice_index, file_name, name, size, shardCount) == true)
{
slice_index += 1;
progressBar1.Value = slice_index;
}
else
{
errorcount++;
if (errorcount > 3)
{
break;
}
}

}
if (slice_index == shardCount)
{
this.label1.Text = "上传成功!";
}
}
public Boolean Uploadfile_slice(int file_slice_index, string file, string name, long size, int shardCount)
{
var temp_file_info = new FileInfo(file);
long start;
long end;
start = file_slice_index * (shardSize);
end = Math.Min((size), start + (shardSize));
int slice_lenth = Convert.ToInt32(end - start);
string my_argument;
string[] msg;
string url = "http://localhost:4088/File/up1.aspx?";
string responseContent;
my_argument = "name=" + name + "&" + "total=" + shardCount + "&" + "size=" + size + "&" + "index=" + Convert.ToString(file_slice_index + 1);
url = url + my_argument;
byte[] my_buffer = new byte[2 * 1024 * 1024];
var webRequest = (HttpWebRequest)WebRequest.Create(url);
try
{
webRequest.Method = "POST";
webRequest.Timeout = 60000;
webRequest.ContentType = "multipart/form-data";
//  webRequest.AllowWriteStreamBuffering = false;
long bytesRead; // =0

var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);

fileStream.Seek(file_slice_index * shardSize, 0);

bytesRead = fileStream.Read(my_buffer, 0, slice_lenth);

var requestStream = webRequest.GetRequestStream();

requestStream.Write(my_buffer, 0, slice_lenth);
requestStream.Flush();

requestStream.Close();

var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
Encoding.GetEncoding("utf-8")))
{
responseContent = httpStreamReader.ReadToEnd();

}
fileStream.Close();
httpWebResponse.Close();
webRequest.Abort();
requestStream = null;
my_buffer = null;
msg = responseContent.Split(Convert.ToChar("|"));
Application.DoEvents();
if (msg[0].ToLower() == "error")
{
this.label1.Text = "上传出错!";
return false;
}
return true;
}
catch (Exception)
{

webRequest.Abort();
return false;
throw;
}

}
}
}

服务端up1.aspx

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class File_up1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string msg = "";
string flag = "";
int total = 0;
long size_total = 0;
int file_index = 0;
try
{ //从Request中取参数,注意上传的文件在Requst.Files中
string name = Request["name"];
total = Convert.ToInt32(Request["total"]);
file_index = Convert.ToInt32(Request["index"]);
size_total = Convert.ToInt64(Request["size"]);

9f9c
var data = Request.InputStream;
string dir = Server.MapPath("~/Upload");
string file_shard = Path.Combine(dir, name + "_" + file_index); //文件片路径及文件名
string part = ""; //文件部分
string file_name = Path.Combine(dir, name); //文件路径及文件名
if (file_index == total)
{
var fs = new FileStream(file_name, FileMode.Create);
for (int i = 1; i <= total; ++i)
{
part = Path.Combine(dir, name + "_" + i);
var bytes = System.IO.File.ReadAllBytes(part);
fs.Write(bytes, 0, bytes.Length);
bytes = null;
System.IO.File.Delete(part);
}
fs.Close();
flag = "ok";    //返回是否成功
}
else
{
byte[] bytes = new byte[data.Length];
data.Read(bytes, 0, bytes.Length);
// 设置当前流的位置为流的开始
data.Seek(0, SeekOrigin.Begin);

// 把 byte[] 写入文件
FileStream fs = new FileStream(file_name, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(bytes);
bw.Close();
fs.Close();
}
}
catch (Exception)
{
flag = "error";    //返回是否成功
}
msg = flag ;
Response.Write(msg);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  大文件 上传