我正在尝试从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)
答案 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, _) }