搜尋
首頁php教程PHP开发jQuery webuploader分片上傳大文件

一般在做文件上傳的時候,都是透過客戶端把要上傳的文件上傳到伺服器,此時上傳的文件都在伺服器內存,如果上傳的是影片等大文件,那麼伺服器記憶體就很緊張,而且一般我們都是用flash或html5做非同步上傳,如果檔案比較大的話,即便是客戶端顯示檔案已經上傳了100%,還是會有一個比較長時間的等待,而且目前頁面對伺服器的請求也會被阻塞。

正常情況下,一般都是在長傳完成後,在伺服器直接保存。

public void ProcessRequest(HttpContext context)
  {
   context.Response.ContentType = "text/plain";
   //保存文件
   context.Request.Files[0].SaveAs(context.Server.MapPath("~/1/" + context.Request.Files[0].FileName));
   context.Response.Write("Hello World");
  }

   

最近專案中以百度開源的上傳元件webuploader,官方介紹webuploader支援分片上傳。

var uploader = WebUploader.create({
   auto: true,
   swf:'/webuploader/Uploader.swf',
   // 文件接收服务端。
   server: '/Uploader.ashx',
   // 内部根据当前运行是创建,可能是input元素,也可能是flash.
   pick: '#filePicker',
   chunked: true,//开启分片上传
   threads: 1,//上传并发数
   //由于Http的无状态特征,在往服务器发送数据过程传递一个进入当前页面是生成的GUID作为标示
   formData: {guid:"<%=Guid.NewGuid().ToString()%>"}
  });

   

webuploader的分片上傳是把文件分成若干份,然後向你定義的文件接收端post數據,如果上傳的文件大於分片的尺寸,就會進行分片,然後會在post的資料中加入兩個form元素chunk和chunks,前者標示目前分片在上傳分片中的順序(從0開始),後者代表總分片數。

選擇一個檔案後分了7個分片,所以對Uploader.ashx進行了7次post資料的過程。

jQuery webuploader分片上傳大文件

每次請求中的form元素chunk和chunks以及為了標示是同一個文件的分片的GUID

jQuery webuploader分片上傳大文件

在伺服器端接收到到,就可以根據這些參數進行處理了。

  1、按按GUID建立一個臨時檔案

  2、把收到的分片資料追加到對應GUID的檔案中。

  3、根據上傳的檔案名稱重新命名臨時檔案

  4、如果沒有分片直接保存

public void ProcessRequest(HttpContext context)
  {
   context.Response.ContentType = "text/plain";
   //如果进行了分片
   if (context.Request.Form.AllKeys.Any(m => m == "chunk"))
   {
    //取得chunk和chunks
    int chunk =Convert.ToInt32(context.Request.Form["chunk"]);
    int chunks = Convert.ToInt32(context.Request.Form["chunks"]);
 
     
    //根据GUID创建用该GUID命名的临时文件
    string path = context.Server.MapPath("~/1/" + context.Request["guid"]);
    FileStream addFile = new FileStream(path, FileMode.Append, FileAccess.Write);
    BinaryWriter AddWriter = new BinaryWriter(addFile);
    //获得上传的分片数据流
    HttpPostedFile file = context.Request.Files[0];
    Stream stream = file.InputStream;
 
    BinaryReader TempReader = new BinaryReader(stream);
    //将上传的分片追加到临时文件末尾
    AddWriter.Write(TempReader.ReadBytes((int)stream.Length));
    //关闭BinaryReader文件阅读器
    TempReader.Close();
    stream.Close();
    AddWriter.Close();
    addFile.Close();
 
    TempReader.Dispose();
    stream.Dispose();
    AddWriter.Dispose();
    addFile.Dispose();
    //如果是最后一个分片,则重命名临时文件为上传的文件名
    if (chunk == (chunks - 1))
    {
     FileInfo fileinfo = new FileInfo(path);
     fileinfo.MoveTo(context.Server.MapPath("~/1/" + context.Request.Files[0].FileName));
    }
   }
   else//没有分片直接保存
   {
    context.Request.Files[0].SaveAs(context.Server.MapPath("~/1/" + context.Request.Files[0].FileName ));
   }
   context.Response.Write("ok");
  }

還存在一些問題沒解決,雖然暫時滿足需求:

個的時候,就會出現一個分片上傳伺服器還沒處理結束,第二個分片同時就到了,那樣就會出現檔案被佔用的錯誤。
2、如果加鎖的辦法解決第一個問題,那麼加鎖了就一定會影響效率(同時只有一個進程能存取保存檔案那段程式碼)。
3、文件的順序問題,有個可能是第二個分片先到,然後第一個才到,那麼就不能一次追加流到臨時文件了,只能創建多個臨時文件,待所有分片上傳完成後,拼接成一個檔案。

只是個Demo,希望有人幫忙解決下存在的問題。


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),