上传大文件-断点续传的一中方式的记录
客户端对文件的分割:
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();
}
}
下一篇: 山洞里的母乌龟