读取S3对象并写入InMemory Buffer

时间:2017-06-13 07:43:28

标签: java scala amazon-web-services amazon-s3 aws-java-sdk

我正在尝试从S3读取并写入InMemory缓冲区,如:

  def inMemoryDownload(bucketName: String, key: String): String = {
  val s3Object = s3client.getObject(new GetObjectRequest(bucketName, key))
  val s3Stream = s3Object.getObjectContent()
  val outputStream = new ByteArrayOutputStream()
  val buffer = new Array[Byte](10* 1024)
  var bytesRead:Int =s3Stream.read(buffer)
  while (bytesRead > -1) {
    info("writing.......")
    outputStream.write(buffer)
    info("reading.......")
    bytesRead = ss3Stream.read(buffer)
  }
  val data = new String(outputStream.toByteArray)
  outputStream.close()
  s3Object.getObjectContent.close()
  data
}

但它给了我堆空间错误(S3上的文件大小是4MB)

1 个答案:

答案 0 :(得分:0)

在写入流时,您应该使用刚读过的thbytes。编写它的方式,每次都写入整个缓冲区。我怀疑这是你的记忆问题的原因,但它可能是。想象一下,read每次都会向您返回一个字节,并在流中写入10K。那是40G,就在那里。

另一个问题是,我不是100%肯定,但我怀疑,getObjectObject每次都会创建一个新的输入流。基本上,你只是在循环中一遍又一遍地读取相同的字节。你应该把它变成一个变量。

另外,如果我可以提出建议,请尝试在实际的scala中重写代码,不仅仅是语法上的,而是惯用的。避免可变状态,并使用功能转换。如果您要编写scala代码,可能需要一些时间才能进入正确的思维模式。你最终会逐渐欣赏它,我保证:)

也许是这样的事情?

val input = s3Object.getObjectContent
Stream
  .continually(input.read(buffer))
  .takeWhile(_ > 0)
  .foreach { output.write(buffer, 0, _) }