如何上传大文件,找了很多资料,看不懂某些代码,一个人开发的小项目,很急!谢谢!

patrickjiang 2015-04-10 01:30:36
工作上需要实现一个大文件上传功能,我找了好多资料,采用了以下方法,但我不太懂,所以求助各位兄弟,谢谢了!!!

//ASPX页面中的文件上传FileUpload、提交按钮Button、结果Label
<form id="form1" runat="server">
<div>
<asp:FileUpload ID="FileUpload1" runat="server" /><br /><br />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /><br /><br />
<asp:Label ID="Label1" runat="server"></asp:Label><br /><br />
</div>
</form>



//ASPX页面的C#代码
protected void Button1_Click(object sender, EventArgs e)
{
string strDesPath = "D:\\";
string strFileName = FileUpload1.PostedFile.FileName;
strFileName = strDesPath + strFileName;

FileUpload1.PostedFile.SaveAs(strFileName);
Label1.Text = "文件保存到了:" + strFileName;
}


以上是页面文件,以下是一个HttpUploadModule类,实现了IHttpModule接口,另外还有一个web.config文件代码:

public class HttpUploadModule : IHttpModule
{
public HttpUploadModule()
{
}

public void Init(HttpApplication application)
{
//订阅事件
application.BeginRequest += new EventHandler(this.Application_BeginRequest);
}

public void Dispose()
{
}

private void Application_BeginRequest(Object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
HttpWorkerRequest request = GetWorkerRequest(app.Context);
Encoding encoding = app.Context.Request.ContentEncoding;

int bytesRead = 0; // 已读数据大小
int read; // 当前读取的块的大小
int count = 8192; // 分块大小
byte[] buffer; // 保存所有上传的数据

if (request != null)
{
// 返回 HTTP 请求正文已被读取的部分。
byte[] tempBuff = request.GetPreloadedEntityBody(); //要上传的文件

// 如果是附件上传
if (tempBuff != null && IsUploadRequest(app.Request)) //判断是不是附件上传
{
// 获取上传大小
//
long length = long.Parse(request.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength));

buffer = new byte[length];
count = tempBuff.Length; // 分块大小

// 将已上传数据复制过去
//
Buffer.BlockCopy(tempBuff, //源数据
0, //从0开始读
buffer, //目标容器
bytesRead, //指定存储的开始位置
count); //要复制的字节数。


// 开始记录已上传大小
bytesRead = tempBuff.Length;

// 循环分块读取,直到所有数据读取结束
while (request.IsClientConnected() && !request.IsEntireEntityBodyIsPreloaded() && bytesRead < length)
{
// 如果最后一块大小小于分块大小,则重新分块
if (bytesRead + count > length)
{
count = (int)(length - bytesRead);
tempBuff = new byte[count];
}

// 分块读取
read = request.ReadEntityBody(tempBuff, count);

// 复制已读数据块
Buffer.BlockCopy(tempBuff, 0, buffer, bytesRead, read);

// 记录已上传大小
bytesRead += read;

}
if (request.IsClientConnected() && !request.IsEntireEntityBodyIsPreloaded())
{
// 传入已上传完的数据
InjectTextParts(request, buffer);
}
}
}
}


HttpWorkerRequest GetWorkerRequest(HttpContext context)
{

IServiceProvider provider = (IServiceProvider)HttpContext.Current;
return (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
}

/// <summary>
/// 传入已上传完的数据
/// </summary>
/// <param name="request"></param>
/// <param name="textParts"></param>
void InjectTextParts(HttpWorkerRequest request, byte[] textParts)
{
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;

Type type = request.GetType();

while ((type != null) && (type.FullName != "System.Web.Hosting.ISAPIWorkerRequest"))
{
type = type.BaseType;
}

if (type != null)
{
type.GetField("_contentAvailLength", bindingFlags).SetValue(request, textParts.Length);
type.GetField("_contentTotalLength", bindingFlags).SetValue(request, textParts.Length);
type.GetField("_preloadedContent", bindingFlags).SetValue(request, textParts);
type.GetField("_preloadedContentRead", bindingFlags).SetValue(request, true);
}
}

private static bool StringStartsWithAnotherIgnoreCase(string s1, string s2)
{
return (string.Compare(s1, 0, s2, 0, s2.Length, true, CultureInfo.InvariantCulture) == 0);
}

/// <summary>
/// 是否为附件上传
/// 判断的根据是ContentType中有无multipart/form-data
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
bool IsUploadRequest(HttpRequest request)
{
return StringStartsWithAnotherIgnoreCase(request.ContentType, "multipart/form-data");
}
}



<configuration>
<connectionStrings>
<add name="TrainingExamConnectionString" connectionString="Data Source=JIANGPENG\SQLEXPRESS;Initial Catalog=TrainingExam;User ID=sa;Password=2112706"
providerName="System.Data.SqlClient" />
<add name="TrainingExamConnectionString2" connectionString="Data Source=KYB-PC\SQLEXPRESS;Initial Catalog=TrainingExam;User ID=sa;Password=2112706"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.webServer>
<modules>
<add name="HttpUploadModule" type="k2hTEWebApp.HttpUploadModule, k2hTEWebApp"></add>
</modules>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
</configuration>


...全文
161 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
patrickjiang 2015-04-12
  • 打赏
  • 举报
回复
@本拉灯 这位老师,您在吗?我上网找到HttpUploader5的ActiveX插件,下载后在VS2012中SQL脚本执行,C#调试,最后卡在它的核心JS库上,说是缺少var files = obj.ShowDialog();方法。我不知道怎么调,请问你有更好的建议吗?谢谢!
patrickjiang 2015-04-10
  • 打赏
  • 举报
回复
@本拉灯 分全给你啦!谢谢!
patrickjiang 2015-04-10
  • 打赏
  • 举报
回复
@本拉灯 太感谢了!!!
本拉灯 2015-04-10
  • 打赏
  • 举报
回复
引用 11 楼 patrickjiang 的回复:
@本拉灯 呵呵,您说的:只要你会把文件分块上传就可以了。这要怎么文件分块上传???
这就是你要学的,一几句话说不完的。你要先学习Activex怎么弄吧,还有这东西 只能用在IE下。 一步一步来
patrickjiang 2015-04-10
  • 打赏
  • 举报
回复
@本拉灯 呵呵,您说的:只要你会把文件分块上传就可以了。这要怎么文件分块上传???
本拉灯 2015-04-10
  • 打赏
  • 举报
回复
引用 9 楼 patrickjiang 的回复:
@本拉灯 类似这样的ActiveX插件吗?http://download.csdn.net/detail/songsu/2232417
是地。用上这个你就可以可以传好几G的文件都没问题 ,只要你会把文件分块上传就可以了。
patrickjiang 2015-04-10
  • 打赏
  • 举报
回复
@本拉灯 类似这样的ActiveX插件吗?http://download.csdn.net/detail/songsu/2232417
本拉灯 2015-04-10
  • 打赏
  • 举报
回复
引用 7 楼 patrickjiang 的回复:
[quote=引用 6 楼 wyd1520 的回复:] [quote=引用 4 楼 patrickjiang 的回复:] [quote=引用 2 楼 wyd1520 的回复:] 上传大文件一般都是结合ActiveX控件的,如果只是靠Asp.net自带的,基本无法做到。 或你要百度一下现在的js能不能读取某个文件的一部份数据流。这好像又关系到了安全的问题 了。 所以唯一的方式就是用Activex控件,Charome的也是一样的要用到相应的DLL
@本拉灯 请问是什么ActiveX控件?[/quote] 就是浏览器插件,只有这东西才有权限读取某个目录下的文件,并只读取这个文件某个部份的数据流。这样才能做到大文件上传。[/quote] @本拉灯 你说的插件是不是JS插件?http://www.open-open.com/ajax/2_Upload.htm类似这些吗?[/quote] 不是那些JS插件读不了那么大的文件,只有Activex才行他就像WINFORM程序样。。
patrickjiang 2015-04-10
  • 打赏
  • 举报
回复
引用 6 楼 wyd1520 的回复:
[quote=引用 4 楼 patrickjiang 的回复:] [quote=引用 2 楼 wyd1520 的回复:] 上传大文件一般都是结合ActiveX控件的,如果只是靠Asp.net自带的,基本无法做到。 或你要百度一下现在的js能不能读取某个文件的一部份数据流。这好像又关系到了安全的问题 了。 所以唯一的方式就是用Activex控件,Charome的也是一样的要用到相应的DLL
@本拉灯 请问是什么ActiveX控件?[/quote] 就是浏览器插件,只有这东西才有权限读取某个目录下的文件,并只读取这个文件某个部份的数据流。这样才能做到大文件上传。[/quote] @本拉灯 你说的插件是不是JS插件?http://www.open-open.com/ajax/2_Upload.htm类似这些吗?
本拉灯 2015-04-10
  • 打赏
  • 举报
回复
引用 4 楼 patrickjiang 的回复:
[quote=引用 2 楼 wyd1520 的回复:] 上传大文件一般都是结合ActiveX控件的,如果只是靠Asp.net自带的,基本无法做到。 或你要百度一下现在的js能不能读取某个文件的一部份数据流。这好像又关系到了安全的问题 了。 所以唯一的方式就是用Activex控件,Charome的也是一样的要用到相应的DLL
@本拉灯 请问是什么ActiveX控件?[/quote] 就是浏览器插件,只有这东西才有权限读取某个目录下的文件,并只读取这个文件某个部份的数据流。这样才能做到大文件上传。
patrickjiang 2015-04-10
  • 打赏
  • 举报
回复
引用 3 楼 starfd 的回复:
单web页面的话,你就只能依赖浏览器了……
@娃都会打酱油了 怎么依赖浏览器?
patrickjiang 2015-04-10
  • 打赏
  • 举报
回复
引用 2 楼 wyd1520 的回复:
上传大文件一般都是结合ActiveX控件的,如果只是靠Asp.net自带的,基本无法做到。 或你要百度一下现在的js能不能读取某个文件的一部份数据流。这好像又关系到了安全的问题 了。 所以唯一的方式就是用Activex控件,Charome的也是一样的要用到相应的DLL
@本拉灯 请问是什么ActiveX控件?
  • 打赏
  • 举报
回复
单web页面的话,你就只能依赖浏览器了……
本拉灯 2015-04-10
  • 打赏
  • 举报
回复
上传大文件一般都是结合ActiveX控件的,如果只是靠Asp.net自带的,基本无法做到。 或你要百度一下现在的js能不能读取某个文件的一部份数据流。这好像又关系到了安全的问题 了。 所以唯一的方式就是用Activex控件,Charome的也是一样的要用到相应的DLL
patrickjiang 2015-04-10
  • 打赏
  • 举报
回复
周围旁边没人,打电话问也没问到!时间要求比较紧,所以请教网上各位兄弟!谢谢了!!!

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧