HTTP协议下用Web Service上传大文件的解决方案

用HTTP协议上传大文件也许是个不好办的问题。主要是它的不连续性,使得上传文件感觉很“危险”。特别是很大的文件(几百MB甚至是上G的文件),心里总觉得不踏实,一不小心就会出现问题,而一但出现问题就无法继续上传,这是很郁闷的。

后来在一些网站上找到一些上传文件的组件,但都是要用到一些COM组件。至于后来的ASP.net下上传大文件的解决方案,我也做过一个组件,后来发现根本就不用自己写什么组件,利用ASP.net自己的上传方法也可以解决大文件上传,真是郁闷的要死了。。。。

回想之后,决定用Web service来做一个文件上传,还是利用HTTP协议,这样不用在服务器上做太多的变动,而客户端也简单。

首先是解决方案的设计:因为Web service可以利用SOAP来传递数据,而且可以传递十进制数据,因此可以想到,在服务上公开一个方法,参数可以是byte数组,这样可以把文件分块的上传到服务器。这一解决方法我做过,但速度很慢。后来在MS上找到一些文章,用MS最新公开的服务组件上传文件,速度快了很多。而自己所要做的就是组织一些安全性的问题。

部份代码:Upload Instance

代码如下:

using System; 
using System.IO; 
using Microsoft.Web.Services2; 
using Microsoft.Web.Services2.Dime;

namespace Webb.WAVE.WinUpload 

/**//// <summary> 
/// Summary description for Controls. 
/// </summary> 
public class UploadInstance2 

Fields#region Fields 
private string m_GUID; 
private DateTime m_uploadTime; 
private long m_fileLength; 
private long m_currentPoint; 
private string m_pathOnserver; 
private long m_userID; 
#endregion

Properties#region Properties 
public long UserID 

get{return this.m_userID;} 
set{this.m_userID=value;} 

public string GUID 

get{return this.m_GUID;} 
set{this.m_GUID=value;} 

public DateTime UploadTime 

get{return this.m_uploadTime;} 
set{} 

public long FileLength 

get{return this.m_fileLength;} 
set{this.m_fileLength=value;} 

public long CurrentPoing 

get{return this.m_currentPoint;} 
set{this.m_currentPoint=value;} 

public string PathOnServer 

get{return this.m_pathOnserver;} 
set{this.m_pathOnserver=value;} 

public string FullPathOnServer 

get 

if(this.m_GUID!=string.Empty&&this.m_pathOnserver!=string.Empty) 

return Path.Combine(this.m_pathOnserver,this.m_GUID+".rem"); 

else 

return string.Empty; 



public string FileName 

get 

if(this.m_GUID!=string.Empty) 

return this.m_GUID+".rem"; 

else 

return string.Empty; 


}

#endregion

public UploadInstance2() 

this.m_GUID = System.Guid.NewGuid().ToString(); 
this.m_uploadTime = System.DateTime.Now; 
this.m_currentPoint = 0; 
this.m_fileLength = 0; 
this.m_pathOnserver = string.Empty; 

public UploadInstance2(string i_path,string i_GUID,long i_fileLength) 

string m_fullPath = Path.Combine(i_path,i_GUID); 
if(!File.Exists(m_fullPath)) return; 
this.m_GUID = i_GUID; 
this.m_uploadTime = System.DateTime.Now; 
this.m_pathOnserver = i_path; 
FileInfo m_fileInfo = new FileInfo(m_fullPath); 
this.m_currentPoint = m_fileInfo.Length; 
this.m_fileLength = i_fileLength; 
}

public bool UploadData(byte[] i_data, long i_currentPoint, int i_dataSize) 

string m_fullPath = this.FullPathOnServer; 
if(!File.Exists(m_fullPath)&&this.m_currentPoint!=0)return false; 
long m_filePoint = new FileInfo(m_fullPath).Length; 
if(m_filePoint!=i_currentPoint) return false; 
FileStream m_fileStream = new FileStream(m_fullPath,FileMode.Append); 
m_fileStream.Write(i_data,0,i_dataSize); 
m_fileStream.Close(); 
return true; 
}

public void AbandantUpload() 

string m_fullPath = this.FullPathOnServer; 
try{File.Delete(m_fullPath);} 
catch{} 
}

public void CreateFile() 

string m_fullPath = this.FullPathOnServer; 
if(!File.Exists(m_fullPath)) 

File.Create(m_fullPath).Close(); 

else 

try 

File.Delete(m_fullPath); 
}catch{} 
File.Create(m_fullPath).Close(); 



}

上传过程:


代码如下:

#region UploadProcess 
public void UploadProcess() 

DateTime m_start = DateTime.Now; 
this.textBox_OutMsg.AppendText("Initialize upload\r\n"); 
if(this.m_upload==null||this.m_uploadGUID==null||this.m_uploadGUID==string.Empty) 
{  
this.textBox_OutMsg.AppendText("Upload instance id error or login to the server faild\r\n"); 
this.textBox_OutMsg.AppendText("Upload faild.\r\n"); 
return; 

this.textBox_OutMsg.AppendText("Open file\r\n"); 
if(this.m_filePath==null||this.m_filePath==string.Empty||!File.Exists(this.m_filePath)) 

this.textBox_OutMsg.AppendText("Open file error\r\n"); 
this.textBox_OutMsg.AppendText("Upload faild.\r\n"); 
return; 

FileInfo m_fileInfo = new FileInfo(this.m_filePath); 
FileStream m_fs = new FileStream(this.m_filePath, FileMode.Open, FileAccess.Read); 
this.textBox_OutMsg.AppendText("Start upload file\r\n"); 
int m_buffer = 10; //KBytes 
long m_currentPoint = 0; 
long m_fileLength = m_fileInfo.Length; 
bool m_uploadResult = false; 
byte[] m_data = new byte[m_buffer*1024]; 
long m_readBytes = m_fs.Read(m_data, 0, m_buffer*1024); 
this.UploadProcessBar.Maximum = 100; 
this.UploadProcessBar.Minimum = 0; 
while(m_readBytes>0) 

MemoryStream m_memoryStream = new MemoryStream(m_data, 0,(int)m_readBytes); 
DimeAttachment dimeAttach = new DimeAttachment("image/gif", TypeFormat.MediaType, m_memoryStream); 
this.m_upload.RequestSoapContext.Attachments.Add(dimeAttach); 
m_uploadResult = this.m_upload.UploadFileData(this.m_uploadInstance,m_currentPoint,m_readBytes); 
if(m_uploadResult) 

m_currentPoint +=m_readBytes; 
m_readBytes = m_fs.Read(m_data,0,m_buffer*1024); 
// this.textBox_OutMsg.AppendText("Uploading:"+m_currentPoint.ToString()+"/"+m_fileLength.ToString()+"\r\n"); 
this.UploadProcessBar.Value = (int)(m_currentPoint*100/m_fileLength); 
this.label_outPercent.Text = this.UploadProcessBar.Value.ToString()+"%"; 

else 

this.textBox_OutMsg.AppendText("Upload file error.\r\n"); 
m_fs.Close(); 
this.m_upload.AbandantUpload(this.m_uploadInstance); 
return; 


this.textBox_OutMsg.AppendText("File upload finished.\r\n"); 
this.button_Cancel.Enabled = false; 
m_fs.Close(); 
this.ResetForm(); 

#endregion

测试项目代码:
http://test.0579fw.com/myfile/kiyeer/客户上传/webbwinupload.zip

出现错误的解决方法:
*****************************************************

引用内容
Error 1 'WinFormTest.localhost.WebbWinUpload' does not contain a definition for 'RequestSoapContext' D:\WebbWinUpload\WinFormTest\WebbWinUpload.cs 448 19 WinFormTest

当你更新Web引用的时候,.net自动生成的Web引用为: 
public class WebbWinUpload : System.Web.Services.Protocols.SoapHttpClientProtocol 
请转化为: 
public class WebbWinUpload : Microsoft.Web.Services2.WebServicesClientProtocol 
查找引用下自动生成的C#文件Reference.cs

(0)

相关推荐

  • HTTP协议入门_动力节点Java学院整理

    HTTP 协议是互联网的基础协议,也是网页开发的必备知识,最新版本 HTTP/2 更是让它成为技术热点. 本文介绍 HTTP 协议的历史演变和设计思路. 一.HTTP/0.9 HTTP 是基于 TCP/IP 协议的应用层协议.它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口. 最早版本是1991年发布的0.9版.该版本极其简单,只有一个命令GET. GET /index.html 上面命令表示,TCP 连接(connection)建立后,客户端向服务器

  • 如何利用http协议发布博客园博文评论

    先给大家介绍下实现原理: 给博文提交评论的实质就是通过http协议服务器发送一个post请求.在发布评论前,我们需要做什么呢?对,是必须要登录的.但登录是另一件事情,我们这里先不讨论.用户登录后,服务器给客户端设置一个cookie.http是无状态的.也就是说客户端向服务器发送请求后,服务器返回响应.一次通信完成.服务器不会记得刚才是谁向自己发送请求.所以客户端需要拿着服务器给自己设定好的cookie向服务器发送请求并告知服务器自己的身份,服务器根据cookie产生响应. 准备工作: 为了完成本

  • http协议详解(超详细)

    http协议学习系列             1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC 1945定义了HTTP/1.0版本.其中最著名的就是RFC 2616.RFC 2616定义了今天普遍使

  • HTTP/2 协议用于 iOS 推送提醒服务 (APNS)

    苹果最近更新了他们的推送提醒服务协议,APNS.这个新版本的协议基于HTTP/2和JSON,相比于旧的二进制协议,新的协议有了巨大改进. 新的APNS协议基于HTTP/2: 新的特性和功能: 基于JSON的请求和响应 对于每个通知,如果成功响应,将会返回200标识 - 不用再去猜测通知是否被接收到 响应错误将会以JSON字符的形式返回 消息的长度从2048个字节增加到4096个字节 连接状态可以通过HTTP/2的ping框架来进行检查 支持主题 通用的推送证书 - 开发和生产使用同一个证书即可

  • HTTP协议简介_动力节点Java学院整理

    TCP协议对应于传输层,而HTTP协议对应于应用层,从本质上来说,二者没有可比性.Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求.Http会通过TCP建立起一个到服务器的连接通道,当本次请求需要的数据完毕后,Http会立即将TCP连接断开,这个过程是很短的.所以Http连接是一种短连接,是一种无状态的连接.所谓的无状态,是指浏览器每次向服务器发起请求的时候,不是通过一个连接,而是每次都建立一个新的连接.如果是一个连接的话,服务器进程中就能

  • 网络传输协议(http协议)

    概述:指服务器和客户端间进行通信时的约束和规范,客户端与服务端的数据交互并不是杂乱无章的,需要遵照(基于)一定的规范进行 常见的协议: a) HTTP.HTTPS 超文本传输协议 b) FTP 文件传输协议 c) SMTP 简单邮件传输协议 本文主要介绍http超文本传输协议. 1.HTTP协议 即超文本传输协议,网站是基于HTTP协议的,例如网站的图片.CSS.JS等都是基于HTTP协议进行传输的.HTTP协议是由从客户机到服务器的请求(Request)和从服务器到客户机的响应(Respons

  • HTTP协议下用Web Service上传大文件的解决方案

    用HTTP协议上传大文件也许是个不好办的问题.主要是它的不连续性,使得上传文件感觉很"危险".特别是很大的文件(几百MB甚至是上G的文件),心里总觉得不踏实,一不小心就会出现问题,而一但出现问题就无法继续上传,这是很郁闷的. 后来在一些网站上找到一些上传文件的组件,但都是要用到一些COM组件.至于后来的ASP.net下上传大文件的解决方案,我也做过一个组件,后来发现根本就不用自己写什么组件,利用ASP.net自己的上传方法也可以解决大文件上传,真是郁闷的要死了.... 回想之后,决定用

  • java web图片上传和文件上传实例详解

    java web图片上传和文件上传 图片上传和文件上传本质上是一样的,图片本身也是文件.文件上传就是将图片上传到服务器,方式虽然有很多,但底层的实现都是文件的读写操作. 注意事项 1.form表单一定要写属性enctype="multipart/form-data" 2.为了能保证文件能上传成功file控件的name属性值要和你提交的控制层变量名一致, 例如空间名是file那么你要在后台这样定义 private File file; //file控件名 private String f

  • JS自定义函数对web前端上传的文件进行类型大小判断

    废话不多说了直接给大家贴js代码了.具体代码如下所示: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <me

  • SSM框架+Plupload实现分块上传大文件示例

    关于Plupload的介绍,相信它的官网http://www.plupload.com/已经给得很详细了.Plupload的上传原理简单点说,就是将用户选中的文件(可多个)分隔成一个个小块,依次向服务器上传,这是它能驾驭上传大文件的原因之一,而且在这个过程可以暂停上传,暂停后再继续上传(异于断点续传).最重要的是,从头到尾没有一点点UI阻塞,保证了用户体验.下面会开始讲Plupload的实现流程,分析原理,并在最后给出效果图. 在此之前先说说我的项目,做的j2ee项目运用到spring+Spri

  • Java中使用WebUploader插件上传大文件单文件和多文件的方法小结

    一.使用webuploader插件的原因说明 被现在做的项目坑了. 先说一下我的项目架构spring+struts2+mybatis+MySQL 然后呢.之前说好的按照2G上传就可以了,于是乎,用了ajaxFileUpload插件,因为之前用图片上传也是用这个,所以上传附件的时候就直接拿来用了 各种码代码,测试也测过了,2G文件上传没问题,坑来了,项目上线后,客户又要求上传4G文件,甚至还有20G以上的..纳尼,你不早说哦... 在IE11下用ajaxFileUpload.js插件上传超过4G的

  • ASP.NET解决上传大文件问题的方法

    上传文件的控件为:FileUpload Asp.Net对上传文件大小有限制.默认情况下用户只能上传4MB大小的文件,这会给用户带来不便.所以如果要上传40MB大小的文件.只能修改配置文件 关键代码如下 复制代码 代码如下: protected void btnSend_Click(object sender, EventArgs e) { try { //上传文件的思路: //获取上传文件的名称,此时为一个全路径的地址 string upFileName = fulFileName.FileNa

  • php上传大文件失败的原因及应对策略

    为什么上传大文件总是失败,但是上传小文件就没有问题.小编也不得其解,网上搜其原因,整理了一篇关于php上传大文件失败的原因和解决办法的文章,分享给大家. 下面分别是各种原因以及解决办法: 第1种情况:文件上传时存放文件的临时目录必须是开启的并且是 PHP 进程所有者用户可写的目录.如果未指定则 PHP 使用系统默认值. php.ini文件中upload_tmp_dir用来说明PHP上传的文件放置的临时目录,要想上传文件,得保证服务器没有关闭临时文件并对该文件夹有写入的权限. 第2种情况:max_

  • asp.net 上传大文件解决方案

    这次在项目中,用到了大文件上传,要上传的文件有100多m,于是研究现在国内使用的大文件上传的组件发现用的比较多的有两个控件AspnetUpload 2.0和Lion.Web.UpLoadModule,另外还有思归在它的博客堂中所说的办法 http://blog.joycode.com/saucer/archive/2004/03/16/16225.aspx   两个控件的方法是:利用隐含的HttpWorkerRequest,用它的GetPreloadedEntityBody 和 ReadEnti

  • Nginx 上传大文件超时解决办法

    Nginx 上传大文件超时解决办法 情况如下:用nginx作代理服务器,上传大文件时(本人测试上传50m的文件),提示上传超时或文件过大. 原因是nginx对上传文件大小有限制,而且默认是1M.另外,若上传文件很大,还要适当调整上传超时时间. 解决方法是在nginx的配置文件下,加上以下配置: client_max_body_size 50m; //文件大小限制,默认1m client_header_timeout 1m; client_body_timeout 1m; proxy_connec

  • Node.js + express实现上传大文件的方法分析【图片、文本文件】

    本文实例讲述了Node.js + express实现上传大文件的方法.分享给大家供大家参考,具体如下: 对于大文件的上传我们首先要引入一个叫做 multer 的库: npm install --save multer 关于这个库,大家可以查阅官方文档: 点击跳转 https://www.npmjs.com/package/multer 我们先将库引入我们的项目中: var multer = require('multer') var upload = multer({ dest: 'upload

随机推荐