首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >上传大文件

上传大文件
EN

Stack Overflow用户
提问于 2012-08-02 14:35:57
回答 1查看 1.3K关注 0票数 3

我是一个业余的ASP.net开发人员,致力于我的第一份工作(一个朋友网站)。ASP.net v4.0,使用VS2010。

他的公司生产3D模型(使用3D打印机)。该网站目前正在开发中,但可以找到这里。我是第一个承认这段代码有点仓促并被黑客入侵的人,但我的朋友对他到目前为止的情况很满意。

其中一个要求是他的客户需要能够上传他们的模型设计文件,每个文件可以高达100 MB (或者更多)。我正努力让这件事正常运作。

我首先使用内置的<asp:FileUpload ID="FileUpload1" runat="server" />标记和一个动画的gif图像,类似于乔·斯塔格纳教程中描述的想法--谢谢乔,我非常喜欢你的演示。

这对于一个小的测试文件来说是可行的,但是没有给出任何上传进度的指示。因此,我试图使用Sunasara在他的代码项目文章中开发的想法来改进我的解决方案。我的上传代码如下所示:

代码语言:javascript
复制
Task t = Task.Factory.StartNew(() =>
{
    byte[] buffer = new byte[UPLOAD_BUFFER_BYTE_SIZE];

    // Upload the file in chunks so that we can measure how long it is taking.
    using (FileStream fs = new FileStream(Path.Combine(newQuotePath, filename), FileMode.Create))
    {
        DateTime stopwatch = DateTime.Now;

        while (stats.Uploaded < stats.TotalSize)
        {
            int bytecount = postedFile.InputStream.Read(buffer, 0, UPLOAD_BUFFER_BYTE_SIZE);
            fs.Write(buffer, 0, bytecount);

            stats.Uploaded += bytecount;

            double dRate = UPLOAD_BUFFER_BYTE_SIZE / Math.Abs((DateTime.Now - stopwatch).TotalSeconds);
            stats.Rate = (int)(Math.Min(dRate, int.MaxValue));

            // Sleep is for debugging only!
            //System.Threading.Thread.Sleep(2000);

            stopwatch = DateTime.Now;
        }
    }
}, TaskCreationOptions.LongRunning);

其中,stats是对作为会话变量存储的类的引用,并通过setInterval(...)中运行的javascript函数(在上传过程中)由PageMethod访问:

代码语言:javascript
复制
[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public static UploadStatus GetFileUploadStatus()
{
    UploadStatus stats = (UploadStatus)HttpContext.Current.Session["UploadFileStatus"];

    if ((stats != null) && (stats.IsReady))
    {
        return stats;
    }
    else
    {
        return null;
    }
}

这在我的本地机器上有效(使用线程休眠来减缓上传速度)。所以我把它发布给了我们的主机123-Reg,它没有像预期的那样工作。当上传开始时,动画gif就会启动,但是进度条不会开始移动。文件输入控件和提交按钮(在IFrame中),上传一开始就会被禁用,需要很长时间才能禁用。然后网页就挂在那里。等待了一段时间后,我单击了页面刷新按钮。当页面刷新时,显示我的测试文件已成功上传。我尝试了一个16 KB的文件和一个1.6MB的文件。

由于这在我的本地机器上工作,我怀疑这是因为我们的网站主机(123-Reg)正在使用一个网络场。

无论如何,我认为这会很容易,但它不是,所以我看了一些开放源码上传进度条。我看了一下NeatUpload,但是它说“默认情况下,NeatUpload不会在网络花园或网络场上正常工作”,它还说要让它在web场上工作,“在每个服务器的Web.config部分指定相同的随机32六位数decryptionKey属性”。但是我不认为我可以访问123 Reg的服务器配置文件(?)。

我的朋友建议,也许我们可以使用像dropbox这样的服务,但我看了一下,我不知道如何把这个添加到我们的网站上。这可能是一个很好的选择,因为他们可能是优化上传。

任何建议或建议都将不胜感激--谢谢。

编辑:到目前为止的故事..。还在为这个而挣扎。

我详细研究了dropbox的使用情况(以及其他云存储提供商,如SkyDrive等)。这些服务似乎是围绕着提供与单个用户存储交互的应用程序而设计的。我希望所有的用户能够上传文件到我的dropbox文件夹,但不共享(客户不应该访问其他客户的设计文件)。无论如何,我继续,设置一个dropbox帐户,安装了Sharpbox并重新编程了我的上传代码(任务操作中的位)。这似乎在我的本地机器上正常工作,它有点慢,因为它正在上传到dropbox服务器(我不需要Thread.Sleep)。我把这个网站发布到123-Reg服务器上,并得到了类似的、无法使用的体验。

到目前为止,我已经在IE9上进行了测试,我碰巧用Chrome尝试了一下,我注意到了一件有趣的事情。点击上传按钮后,在页面刷新之前,Chrome在左下角显示了上传%完成对话框。这是100%,然后我的控件开始显示一些操作,然后整个页面又开始挂起。

根据MSDN的HttpPostedFile:“默认情况下,所有大于256 KB的请求,包括表单字段和上传的文件,都被缓冲到磁盘上。”

那么,这是否意味着我的任务是在等待上传的痛苦部分之后开始的(这实际上是在客户机和缓冲区之间发生的)?如果是这样的话,那么通过将文件发送到dropbox来让它变得更加痛苦是没有意义的,对吧?我的进度条是跟踪错误位的进度吗?

(今天,我将检查代码的错误处理,因为我有一种感觉,它挂起的原因是因为它没有从异常恢复正常)。当然,我觉得通过这样做我学到了很多东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-03 09:18:13

这可能有点过火,但您可以考虑使用BluImp的jQuery文件上传工具(这里是演示站点:http://blueimp.github.com/jQuery-File-Upload/ )--一个名为Max的开发人员已经修改了最初的版本(最初用于非dotnet技术),以便在MVC 3中使用。

它可以在git集线器https://github.com/maxpavlov/jQuery-File-Upload.MVC3上找到。我已经成功地在MVC 3和MVC 4 Beta中实现了这一点。要使它在MVC 4中有效工作,我必须做的唯一一件事就是删除一些ClientDependancy (这是一个处理JS和CSS文件捆绑和缩小的DLL )代码,因为这可以复制MVC 4中已经存在的功能,而不是MVC 3中的功能。此外,我还在GitHub上向wiki添加了一些页面,描述了我所做的事情,尽管它还没有完成。如果你决定沿着这条路线走下去,我可以用我最近的发现来更新一些细节。到目前为止,我关于MVC 4集成的说明可以在这里找到https://github.com/maxpavlov/jQuery-File-Upload.MVC3/wiki/MVC-4---EnableDefaultBundles

顺便说一句,我已经设法上传文件高达2Gb使用这个工具,并发现它相当灵活!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11779751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档