我是一名業餘ASP.net開發人員,負責我的第一份工作(朋友網站)。 ASP.net v4.0,使用VS2010。上傳大文件
他的公司生產3D模型(使用3D打印機)。該網站目前正在開發中,但可以找到here。我會第一個承認代碼有點匆匆入侵,但我的朋友對他到目前爲止很滿意。
其中一個要求是他的客戶需要能夠上傳他們的模型設計文件,每個文件可能高達100 MB(或者更多)。我努力讓這個工作正常。
我開始使用內置的<asp:FileUpload ID="FileUpload1" runat="server" />
標籤和一個動畫gif圖像,類似於Joe Stagner's tutorial中描述的想法 - 感謝喬,我非常喜歡您的演示文稿。
這對一個小測試文件工作正常,但沒有給出任何上傳進度的跡象。所以我試圖用他的code project article中Sunasara Imdadhusen開發的想法改進我的解決方案。我上傳的代碼如下所示:
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
是存儲爲一個會話變量類的引用,並從一個JavaScript函數在setInterval(...)
運行(而上傳正在發生)的訪問該PageMethod:
[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.6 MB的文件。
因爲這在我的本地機器上工作,我懷疑這是因爲我們的網站主機(123-Reg)正在使用網絡農場。
無論如何,我認爲這會很容易,但事實並非如此,所以我找了一些開源上傳進度條。我看了一下NeatUpload,但它說「默認情況下,NeatUpload在網上花園或網上農場不能正常工作」,並且它也說讓它在Web場上工作「指定相同的隨機32-每個服務器的Web.config部分中的數字解密密鑰屬性「。但我不認爲我有權訪問123-Reg的服務器配置文件(?)。
我的朋友建議,也許我們可以使用服務,如dropbox,但我看了一下,我不知道如何將其添加到我們的網站。這可能是一個不錯的選擇,因爲它們可能針對上傳進行了優化。
任何意見或建議將非常感謝 - 謝謝。
編輯:到目前爲止的故事......仍然與此掙扎。
我仔細研究了使用Dropbox(以及其他雲存儲提供商,如SkyDrive等)。似乎這些服務是圍繞提供與個人用戶存儲交互的應用程序而設計的。我希望所有用戶能夠將文件上傳到我的Dropbox文件夾,但不共享(客戶不應訪問其他客戶的設計文件)。無論如何,我繼續,設置一個Dropbox帳戶,安裝Sharpbox SDK並重新編程我的上傳代碼(任務操作中的位)。這似乎在我的本地計算機上工作正常,但速度稍慢,因爲它正在上傳到保管箱服務器(我不需要Thread.Sleep)。我將網站發佈到123-Reg服務器,並得到了與以前類似的無法使用的體驗。
到目前爲止,我一直在IE9上進行測試,並且我只是想用Chrome瀏覽器進行測試,而且我注意到了一個有趣的事情。只需點擊上傳按鈕,但在刷新頁面之前,Chrome在左下角顯示一個上傳%完成對話框。這運行到100%,然後我的控件在整個頁面再次掛起之前開始顯示一些操作。
根據MSDN的HttpPostedFile: 「默認情況下,所有的請求,包括表單字段和上傳文件,大於256 KB的緩存到磁盤」
那麼,這是否意味着以後我的工作正在啓動等待上傳的痛苦部分(實際上發生在客戶端和緩衝區之間)?如果是這種情況,那麼通過將文件發送到Dropbox的方式使它更加痛苦是沒有意義的?我的進度條正在跟蹤錯誤的進度? (今天我要檢查我的代碼的錯誤處理,因爲我有一種感覺,它掛起的原因是因爲它沒有正確地從異常恢復)。這當然讓我感覺我正在學習很多東西。
使用雲代替,如果它不貴,或者購買hostin自己的服務器。似乎託管提供商限制了請求大小。 – 2012-08-02 14:47:35
根據[serialseb的帖子](http://stackoverflow.com/a/1156906/340045):只要您使用HttpRequest.InputStream,Asp.net就會始終加載整個請求內容,所以我想這可能會導致一些問題對我來說。 – Ben 2012-08-04 11:43:40