4

在我的应用程序中,我试图将文件上传到目标文件夹,浏览器不允许我上传大于 4 GB 的文件,我的文件大小为 15 GB。我在这里感到震惊,不知道如何上传它。任何帮助都是非常可观的。

4

1 回答 1

18

您可以分两个阶段解决此问题:

  1. 您需要将大文件拆分成更小的块,然后将它们发送到服务器。为此,您可以使用一些javascript库,例如Resumable.js
  2. 在你的 play2 控制器中,你需要使用IterateeAPI 组装这些块,然后你可以对你的文件做任何你想做的事情。

编辑:

让我们resumable.js以客户端为例,我不会深入细节,您可以在此处找到文档和示例

我们的观点将是极简主义的(仅链接选择一个或多个文件):

@()
@main("File upload"){
    <a href="#" id="browseButton">Select files</a>
}

我们的 javasctipt :

$(function(){
  var r = new Resumable({
    target:'/test/upload'
  });

  r.assignBrowse(document.getElementById('browseButton'));

  r.on('fileSuccess', function(file){
    console.debug(file);
  });
  r.on('fileProgress', function(file){
    console.debug(file);
  });
  // more events, look API docs
});

我们的 main.scala.html :

@(title: String)(content: Html)

<!DOCTYPE html>

<html>
    <head>
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
        <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/style.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
        <script src="@routes.Assets.at("javascripts/jquery-1.9.0.min.js")" type="text/javascript"></script>
        @*We include resumable.js library*@
        <script src="@routes.Assets.at("javascripts/resumable.js")" type="text/javascript"></script>
        @*Our javascript for file upload*@
        <script src="@routes.Assets.at("javascripts/upload.js")" type="text/javascript"></script>
    </head>
    <body>
        @content
    </body>
</html>

而我们的服务器端,在播放控制器:

首先,我们需要创建一个函数,该函数将通过使用我们的 chank 并产生结果来处理我们的文件部分 - 在我们的示例中为 Array[Byte]。

 // hadle file part as Array[Byte]
  def handleFilePartAsByteArray: PartHandler[FilePart[Array[Byte]]] =
    handleFilePart {
      case FileInfo(partName, filename, contentType) =>
        // simply write the data to the a ByteArrayOutputStream
        Iteratee.fold[Array[Byte], ByteArrayOutputStream](
          new ByteArrayOutputStream()) { (os, data) =>
          os.write(data)
          os
        }.mapDone { os =>
          os.close()
          os.toByteArray
        }

然后我们可以定义一个自定义的正文解析器:

// custom body parser to handle file part as Array[Byte]
  def multipartFormDataAsBytes:BodyParser[MultipartFormData[Array[Byte]]] =
    multipartFormData(handleFilePartAsByteArray)

最后我们的控制器可能看起来像:

def handleFileUpload = Action(multipartFormDataAsBytes){ request =>
 // retrieve file name from data part   
 val fileName  = request.body.asFormUrlEncoded.get("resumableFilename").get.headOption
 // retrieve arrays of byte from file part and write them to file
    request.body.files foreach{
      case FilePart(key,filename,content,bytes)=>
        import scalax.io._
        val output:Output = Resource.fromFile(fileName.getOrElse("default"))
        output.write(bytes)
    }
    Ok("")
  }

控制器的进口清单:

import play.api.mvc._
import play.api.mvc.BodyParsers.parse.Multipart._
import play.api.libs.iteratee.Iteratee
import java.io.ByteArrayOutputStream
import play.api.mvc.BodyParsers.parse._
import play.api.mvc.BodyParsers.parse.Multipart.FileInfo
import play.api.mvc.MultipartFormData.FilePart
于 2013-09-30T08:39:56.373 回答