【问题标题】:store (binary) file - play framework using scala in heroku存储(二进制)文件 - 在 heroku 中使用 scala 播放框架
【发布时间】:2013-10-31 09:38:36
【问题描述】:

我正在尝试将用户上传的图像存储在我的应用程序中,该应用程序由 scala 编写并播放框架 2.2.x 我已经在heroku中部署了我的应用程序。 Heroku 不允许我将文件保存在文件系统中。 所以我尝试将我的文件存储在数据库中。

这是我用于存储图像的代码:

def updateImage(id: Long, image: Array[Byte]) = {
val selected = getById(id)

DB.withConnection {
  implicit c =>
    SQL("update subcategory set image={image} where id = {id}").on('id -> id, 'image -> image).executeUpdate()
}
selected }

这是我用来检索图像的代码:

  def getImageById(id: Long): Array[Byte] = DB.withConnection {
  implicit c =>
  val all = SQL("select image from subcategory where id = {id}").on('id -> id)().map {

    case Row(image: Array[Byte]) => image
    case Row(Some(image: Array[Byte])) => image

    case Row(image: java.sql.Blob )=> image.getBytes(0 , image.length().toInt)
  }
  all.head
 }

问题是:当我使用 H2 数据库和 blob 列时,出现“匹配错误”异常。 当我使用 Postgresql 和 bytea 列时,我没有收到任何错误,但是当我检索图像时,它是十六进制格式,并且数组开头的一些字节丢失了。

【问题讨论】:

  • 在数据库中存储 blob 图像确实是一个非常糟糕的主意。当我看到这样的事情时,我感到很脏。尝试将您的图像保存在 Amazon S3 之类的云存储中,或者 imageshack 更好,除非您不会在网页中显示此图像。还要尝试在客户端执行与图像处理相关的所有操作,例如调整大小、裁剪,因为 Heroku 没有好的工作解决方案。
  • Thanx Ben,但我是新玩框架(和 scala)的新手,找不到关于如何在游戏中使用 Amazon S3 的好教程。

标签: scala playframework anorm


【解决方案1】:

根据PostgreSQL documentationbytea将数组的长度存储在数组开头的四个字节中。当您读取该行时,它们会被剥离,因此当您将 Scala 中的数据与 DB 中的数据进行比较时,它们似乎“缺失”了。

如果您希望网络浏览器正确显示图像,则必须将响应的内容类型设置为适当的值,否则它不知道它正在接收图像数据。 Ok.sendFile 助手会为你做这件事。否则,您将不得不手动操作:

  def getPicture = Action {
      SimpleResult(
          header = ResponseHeader(200),
          body = Enumerator(pictureByteArray))
      .as(pictureContentType)
  }

在上面的示例中,pictureByteArray 是包含数据库中图片数据的 Array[Byte]pictureContentType 是具有适当内容类型的字符串(例如,image/jpeg)。

这在Play documentation 中得到了很好的解释。

【讨论】:

  • 这不是问题。你提到的四个字节完全是postgre的内部结构,就我而言,就我而言,我从DB读取的数组与我写入的数组完全不同。它的大小是 2*x - 1(给定 x 是原始大小),它的编码就像我从未见过的一样。
  • 嗯,你确实说过开头的一些字节丢失了。当您在 pgAdmin 中查看数据时,数据看起来如何?是否正确存储?您使用什么编码从图像文件中检索字节?您需要使用 ISO-8859-1。您如何检索/显示从数据库中获得的数组?如果它是一个十六进制字符串而不是一个字节数组,它将是您传递的数组的两倍。
  • 我在没有任何编码的情况下写入数据并读取它。在 pgadmin 中,我看到了我所期望的。但是当我用同样的查询从 play 中读到它时,我得到了别的东西。例如,当我存储字符“A”时,我得到“!” .当我存储“AA”时,我会得到另外三个字符!!!
猜你喜欢
  • 1970-01-01
  • 2021-08-05
  • 2015-04-09
  • 2015-08-03
  • 2013-09-22
  • 2015-06-09
  • 2013-07-11
  • 2016-08-03
  • 1970-01-01
相关资源
最近更新 更多