【问题标题】:Getting filename only from Scala/ Play仅从 Scala/Play 获取文件名
【发布时间】:2018-07-24 13:52:38
【问题描述】:

我正在使用 Scala/Play 上传文件。

使用我的 scala.html,我有

@helper.form(action = routes.HomeController.uploadFile,
    'enctype -> "multipart/form-data") {
    <input type = "file" name = "picture">
    <p>
        <input type="submit">
    </p>
}

上传文件并指向具有的控制器,

 import org.apache.commons.io.FilenameUtils
import javax.inject._
import play.api._
import play.api.mvc._
import play.api.i18n.Messages.Implicits._
import play.api.Play.current
import play.api.data.Forms._
import play.api.data.Form
import models.MemberService




 def uploadFile = Action(parse.multipartFormData) { request =>
    request.body.file("picture").map { picture =>
      import java.io.File

      val filename = FileNameUtils.getName(picture.filename)
      picture.ref.moveTo(new File(s"/tmp/$filename"))
      Ok("upload completed")
    }.getOrElse {
      Redirect(routes.HomeController.index).flashing("error" -> "nofile exist")
    }
  }

我收到 InvalidPathException 错误。

[InvalidPathException: Illegal char <:> at index 6: \tmp\C:\Users\jungj\Downloads\play-scala-starter-example.zip]

build.sbt

这是我的 build.sbt

name := """play-scala"""
version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.7"

libraryDependencies ++= Seq(
  jdbc,
  cache,
  ws,
  "commons-io" % "commons-io" % "2.6",
  "com.typesafe.play" %% "anorm" % "2.5.0",
  "mysql" % "mysql-connector-java" % "5.1.34",
  "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test


)

resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"

fork in run := true

我猜我的 val 文件名包含路径的全名,它会导致这种情况。 我可能必须删除目录并仅获取文件名并将其放入 val 文件名中才能移动到正确的路径。我对 scala/play 很陌生,想要一些详细的解释。有人可以帮忙吗?

【问题讨论】:

  • 这条路径 (\tmp\C:\Users\jungj\Downloads\play-scala-starter-example.zip) 完全搞砸了。在 Windows 系统中,路径看起来像这样 - C:\abc\def.txtwhere 在基于 Unix/Linux 的系统中,路径看起来像这样 - /abc/def.txt。无论您使用哪种操作系统,您提供的路径显然都是无效路径。
  • 显然是路径问题。因为 new File(s"/tmp/$filename") 创建了 \tmp\C:\Users\jungj\Downloads\play-scala-starter-example.zip。我猜文件名完全包括路径和名称(C:\Users\jungj\Downloads\play-scala-starter-example.zip。)我假设只获取文件名(没有路径)可以是一个开始。
  • 你为什么不尝试用“\”分割它并取最后一个。

标签: scala playframework


【解决方案1】:

picture.filename得到的文件名描述了上传文件在用户电脑上的实际路径。

在这种情况下,用户使用的是 windows 机器,文件的实际路径是C:\Users\jungj\Downloads\play-scala-starter-example.zip

因此,/tmp/$filename 的值将是 /tmp/C:\Users\jungj\Downloads\play-scala-starter-example.zip,这将是一个完全无效的路径。

因此,您真正需要的是一种从用户计算机的外部路径中可靠地提取实际文件名的方法。

您可以为此使用org.apache.commons.io.FilenameUtils

添加 commons.io 作为依赖项(在您的 build.sbt 中),

libraryDependencies += "commons-io" % "commons-io" % "2.6"

现在您可以按如下方式提取文件名,

import org.apache.commons.io.FilenameUtils

val filename = FilenameUtils.getName(picture.filename)

【讨论】:

  • 此处无法导入 FilenameUtils。你能再给我一点帮助吗?
  • 导致编译错误,未找到:value FileNameUtils
  • 它是FilenameUtils 而不是FileNameUtils。那是一个错字。
  • 感谢您的帮助。更正错字后,我能够获得适当的路径,但仍然存在问题:[NoSuchFileException: C:\Users\jungj\AppData\Local\Temp\playtemp3096865473101773127\multipartBody2012383688196248099asTemporaryFile -&gt; \tmp\sample-applications-master.zip] 我认为picture.ref.moveTo(new File(s"/tmp/$filename")) 是从“带有名称的路径”中复制文件(如果我能找到这种方法会很有帮助实际上是为了)但只是将名称切换到尚未构建的位置并不能帮助我上传和复制文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多