>  기사  >  php教程  >  jQuery 웹 업로더는 대용량 파일을 부분적으로 업로드합니다.

jQuery 웹 업로더는 대용량 파일을 부분적으로 업로드합니다.

高洛峰
高洛峰원래의
2016-12-07 14:19:383035검색

일반적으로 파일 업로드 시 업로드할 파일은 클라이언트를 통해 서버에 업로드되는데, 이때 업로드된 파일은 모두 서버 메모리에 들어있습니다. 매우 빡빡하며 일반적으로 비동기 업로드에 플래시나 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");
  }

최근 프로젝트에서는 Baidu의 오픈소스 업로드 구성 요소인 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의 멀티파트 업로드는 파일을 여러 부분으로 나눈 후, 업로드한 파일이 다음과 같으면 정의한 파일 수신자에게 데이터를 게시하는 것입니다. 분할된 것보다 큰 조각의 크기가 조각화되고 두 개의 양식 요소 청크와 청크가 게시물 데이터에 추가됩니다. 전자는 업로드된 조각에서 현재 조각의 순서를 나타내며(0부터 시작) 후자는 총 조각 수를 나타냅니다.

파일을 선택한 후 7개의 샤드로 나누어서 Uploader.ashx에 데이터를 올리는 과정을 총 7번 수행했습니다.

jQuery 웹 업로더는 대용량 파일을 부분적으로 업로드합니다.

각 요청의 양식 요소 청크 및 청크와 동일한 파일의 조각임을 나타내는 GUID

jQuery 웹 업로더는 대용량 파일을 부분적으로 업로드합니다.

서버 측에서 데이터를 수신한 후 이러한 매개변수에 따라 처리할 수 있습니다.

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");
  }

이 있습니다 여전히 일부 문제가 해결되지 않았지만 당분간 요구 사항은 충족됩니다.

1. 동시 업로드가 1개 이상인 경우 분할 업로드 서버가 처리를 완료하지 못하고 두 번째 분할은 동시에 도착하면 파일이 사용 중이라는 오류가 발생합니다.
2. 잠금으로 첫 번째 문제가 해결되면 잠금은 효율성에 확실히 영향을 미칩니다(동시에 하나의 프로세스만 파일을 저장하는 코드에 액세스할 수 있습니다).
3. 파일 순서에 문제가 있습니다. 두 번째 조각이 먼저 도착한 다음 첫 번째 조각이 도착할 수 있습니다. 그러면 임시 파일에 스트림을 한 번에 추가할 수 없습니다. 임시 파일입니다. 멀티파트 업로드가 완료되면 하나의 파일로 합쳐집니다.

단지 데모일 뿐입니다. 누군가가 기존 문제를 해결하는 데 도움을 줄 수 있기를 바랍니다.


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.