欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

上传大文件-断点续传的一中方式的记录

程序员文章站 2023-01-19 10:10:42
客户端对文件的分割: ind.IsBusy = true; ind.Text = "上传中...."; string cs_str = "server=" + GlobalVars.g_ServerID + "&userid="+GlobalVars.g_userID; string url = G ......

客户端对文件的分割:

ind.isbusy = true;
ind.text = "上传中....";
string cs_str = "server=" + globalvars.g_serverid + "&userid="+globalvars.g_userid;
string url = globalvars.upload_image_address + "/page/uploadprogramvedio.aspx";
threadpool.queueuserworkitem(new waitcallback(obj =>
{
try
{
int bufferlength = 1048576;//设置每块上传大小为1m
byte[] buffer = new byte[bufferlength];

//已上传的字节数
long offset = 0;
int count = 1;//当前的块号
int g_count = convert.toint32(g_st.length / bufferlength); //总的块号
if (g_st.length % bufferlength>0)
{
g_count++;
}
if (count == g_count)
{
bufferlength = convert.toint32(g_st.length);
buffer = new byte[bufferlength];
}
//开始上传时间
int size = g_st.read(buffer, 0, bufferlength);

while (size > 0)
{
if (close_flag)
{
return;
}
offset += size;
double pec = math.round(convert.todouble(count*100 / g_count));
this.dispatcher.begininvoke(new action(() =>
{
ind.text = "上传中...." + pec + "%";
}));
//stream st = new memorystream();
//st.write(buffer, 0, bufferlength);
string ccc_str = cs_str +"&chunk=" +count+ "&chunks="+g_count;
string xx = globalvars.httpuploadfile(url, ccc_str, "pic_upload", filename, buffer);
if (xx.contains(fileextension))
{
if (count==g_count)
{
int k = xx.indexof(fileextension);
file_path = xx.substring(0, k + fileextension.length);
this.dispatcher.begininvoke(new action(() =>
{
ind.isbusy = false;
upload_flag = true;
messagebox.show("上传成功!");
}));
}
}
else if (xx.contains("200"))
{
int k = xx.indexof("200");
string str_count= xx.substring(0, k + 3);
if (str_count.contains(":"))//断点续传
{
string[] sstr = str_count.split(':');
int new_chunk = 0;//断点续传后开始的第一块
if (int.tryparse(sstr[0],out new_chunk))
{
new_chunk--; //保险起见防止最后一块的问题,减一
if (count < new_chunk)
{
for (int i = count; i < new_chunk; i++)
{
count++;
size = g_st.read(buffer, 0, bufferlength);
offset += size;
}
}
}
}
}
else
{
this.dispatcher.begininvoke(new action(() =>
{
ind.isbusy = false;
messagebox.show("上传失败!");
}));
break;
}
//st.close();
count++;
if (count == g_count)
{
bufferlength = convert.toint32(g_st.length - offset);
buffer = new byte[bufferlength];
size = g_st.read(buffer, 0, bufferlength);
}
else
{
size = g_st.read(buffer, 0, bufferlength);
}
}
g_st.close();
}
catch (exception ex)
{
this.dispatcher.begininvoke(new action(() =>
{
ind.isbusy = false;
messagebox.show("上传失败!" + ex.tostring());
}));
}
finally
{
//imgfilebytes = null;
g_st.close();
g_st = null;
}
}));

 

http 上传文件的方法:

/// <summary>
/// http上传文件
/// </summary>
/// <param name="url">url地址</param>
/// <param name="poststr">参数 user=eking&pass=123456</param>
/// <param name="fileformname">文件对应的参数名</param>
/// <param name="filename">文件名字</param>
/// <param name="bt">文件流</param>
/// <returns></returns>
public static string httpuploadfile(string url, string poststr, string fileformname, string filename, byte[] bt,stream stream = null )
{
try
{
// 这个可以是改变的,也可以是下面这个固定的字符串
string boundary = "ceshi";

// 创建request对象
httpwebrequest webrequest = (httpwebrequest)webrequest.create(url);
webrequest.contenttype = "multipart/form-data;boundary=" + boundary;
webrequest.method = "post";

// 构造发送数据
stringbuilder sb = new stringbuilder();

// 文本域的数据,将user=eking&pass=123456 格式的文本域拆分 ,然后构造
if (poststr.contains("&"))
{
foreach (string c in poststr.split('&'))
{
string[] item = c.split('=');
if (item.length != 2)
{
break;
}
string name = item[0];
string value = item[1];
sb.append("--" + boundary);
sb.append("\r\n");
sb.append("content-disposition: form-data; name=\"" + name + "\"");
sb.append("\r\n\r\n");
sb.append(value);
sb.append("\r\n");
}
}
else
{
string[] item = poststr.split('=');
if (item.length != 2)
{
return "500";
}
string name = item[0];
string value = item[1];
sb.append("--" + boundary);
sb.append("\r\n");
sb.append("content-disposition: form-data; name=\"" + name + "\"");
sb.append("\r\n\r\n");
sb.append(value);
sb.append("\r\n");
}

// 文件域的数据
sb.append("--" + boundary);
sb.append("\r\n");
sb.append("content-type:application/octet-stream");
sb.append("\r\n");
sb.append("content-disposition: form-data; name=\"" + fileformname + "\"; filename=\"" + filename + "\"");
sb.append("\r\n\r\n");

string postheader = sb.tostring();
byte[] postheaderbytes = encoding.utf8.getbytes(postheader);

//构造尾部数据
byte[] boundarybytes = encoding.utf8.getbytes("\r\n--" + boundary + "--\r\n");

//string filepath = @"c:/2.html";
//string filename = "2.html";

//byte[] filecontentbyte = new byte[1024]; // 文件内容二进制
if (bt != null && stream == null)
{
long length = postheaderbytes.length + bt.length + boundarybytes.length;
webrequest.contentlength = length;
}
else if (bt == null && stream != null)
{
long length = postheaderbytes.length + stream.length + boundarybytes.length;
webrequest.contentlength = length;
}

stream requeststream = webrequest.getrequeststream();

// 输入头部数据 要按顺序
requeststream.write(postheaderbytes, 0, postheaderbytes.length);

// 输入文件流数据
if (bt != null && stream == null)
{
requeststream.write(bt, 0, bt.length);
}
else if (bt == null && stream != null)
{
stream.copyto(requeststream);
}

// 输入尾部数据
requeststream.write(boundarybytes, 0, boundarybytes.length);
webresponse responce = webrequest.getresponse();
stream s = responce.getresponsestream();
streamreader sr = new streamreader(s);

// 返回数据流(源码)
return sr.readtoend();
}
catch (exception ex)
{
globalfunc.logerror("httpuploadfile错误:" + ex.message + ex.stacktrace);
return "500";
}
finally
{
if (stream!=null)
{
stream.close();
}
}
}

 

服务端方法:

protected void doupload()
{
int rand_flag = 0;//0为随机名 1为默认值
string imageroot = "";
if (configurationmanager.connectionstrings["upload_image_path"] != null)
{
imageroot = configurationmanager.connectionstrings["upload_image_path"].connectionstring;
if (imageroot.endswith("/"))
{
imageroot = imageroot.substring(0, imageroot.length - 1);
}
}

if (imageroot == null || imageroot == "")
{
response.write("<script language='javascript'>alert('请配置视频目录!'); window.location.reload();</script>");
response.end();
}
server_id = request["server"];
user_id = request["userid"];
int chunk = convert.toint32(request["chunk"]); //当前分块
int chunks = convert.toint32(request["chunks"]);//总的分块数量
if (!int.tryparse(request["rand_flag"],out rand_flag))
{

}
if (request.files["pic_upload"].contentlength > 0)//验证是否包含文件
{
string filename = request.files["pic_upload"].filename;
string newfilename = filename;
if (chunks > 1)
{
newfilename = chunk + "_" + filename; //按文件块重命名块文件
}
//取得文件的扩展名,并转换成小写
string fileextension = path.getextension(request.files["pic_upload"].filename).tolower();
//filename += fileextension;//完整文件名
//图片目录规则: 网站根目录 +serverid(目录名)+images(目录名)+ userid(目录名)+图片文件名
string virtul_filepath = "/vedio/" + server_id + "/" + user_id+"/";//相对路径
string filepath = imageroot + virtul_filepath;//绝对路径

if (directory.exists(filepath) == false)//如果不存在就创建file文件夹,及其缩略图文件夹
{
try
{
directory.createdirectory(filepath);
}
catch (exception ex)
{
response.write("<script language='javascript'>alert('生成路径出错!" + ex.message + "'); window.location.reload();</script>");
response.end();
}
}

string virtual_allfilename = virtul_filepath + newfilename;// 包含相对路径的文件名
string allfilename = filepath + newfilename;// 包含绝对路径的文件名

if (chunks > 1&& system.io.file.exists(allfilename))
{
for (int i = 1; i < chunks; i++)
{
//检测已存在磁盘的文件区块
if (!system.io.file.exists(filepath + i.tostring() + "_" + filename))
{
response.write(i+":200");
return;
}
}
}
string name = "";
random rd = new random();
name = datetime.now.tostring("yyyymmddhhmmss") + rd.next(1000, 9999)+ fileextension;
if (chunks == 1)
{
if (rand_flag == 1)
{
allfilename = filepath + filename;
virtual_allfilename = virtul_filepath + filename;
}
else
{
allfilename = filepath + name;
virtual_allfilename = virtul_filepath + name;
}
}

request.files["pic_upload"].saveas(allfilename);//保存文件

//将保存的路径,图片备注等信息插入数据库
try
{
if (chunks == 1)
{
response.write(virtual_allfilename);
}
else if (chunks > 1 && chunk == chunks) //判断块总数大于1 并且当前分块==块总数(指示是否为最后一个分块)
{
if (rand_flag==1)
{
using (filestream fsw = new filestream(filepath + filename, filemode.create, fileaccess.readwrite))
{
// 遍历文件合并
for (int i = 1; i <= chunks; i++)
{
var data = system.io.file.readallbytes(filepath + i.tostring() + "_" + filename);
fsw.write(data, 0, data.length);
system.io.file.delete(filepath + i.tostring() + "_" + filename); //删除指定文件信息
}

fsw.position = 0;
response.write(virtul_filepath + filename);
}
}
else
{
using (filestream fsw = new filestream(filepath + name, filemode.create, fileaccess.readwrite))
{
// 遍历文件合并
for (int i = 1; i <= chunks; i++)
{
var data = system.io.file.readallbytes(filepath + i.tostring() + "_" + filename);
fsw.write(data, 0, data.length);
system.io.file.delete(filepath + i.tostring() + "_" + filename); //删除指定文件信息
}
fsw.position = 0;
response.write(virtul_filepath + name);
}
}

}
else
{
response.write("200");
}
}
catch (exception ex)
{
response.write("<script language='javascript'>alert('上传出错!" + ex.message + "'); window.location.reload();</script>");
response.end();

}

}
else
{

response.write("<script language='javascript'>alert('请选择要上传的文件!'); window.location.reload();</script>");
response.end();
}
}