2017-06-13 1 views
1

Ich versuche, aus S3 und das Schreiben in InMemory Puffer zu lesen wie:lesen S3 Objekt und schreiben in InMemory Buffer

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 
} 

Aber es gibt mir Heap-Speicher-Fehler (Größe der Datei auf dem S3 ist 4MB)

+0

Möglicherweise müssen Sie den Heapspeicher überprüfen. Es wird auch nicht empfohlen, 4-MB-Daten im Heap-Speicher zu haben. – notionquest

+0

Meine JVM-Heap-Größe ist 1G. – developer

Antwort

0

Sie sollten Thytes verwenden, die Sie gerade gelesen haben, wenn Sie in den Stream schreiben. Die Art, wie Sie es geschrieben haben, schreibt jedes Mal den gesamten Puffer. Ich bezweifle, dass das die Ursache für Ihr Gedächtnisproblem ist, aber es könnte sein. Stellen Sie sich vor, dass read jedes Mal ein einzelnes Byte an Sie zurückgibt und Sie 10K in den Stream schreiben. Das ist 40G, genau dort.

Ein anderes Problem ist, dass ich nicht 100% sicher bin, aber ich vermute, dass getObjectObject jedes Mal einen neuen Eingabestrom erstellt. Im Grunde lesen Sie einfach immer wieder dieselben Bytes in der Schleife. Sie sollten es stattdessen in eine Variable einfügen.

Auch, wenn ich einen Vorschlag machen kann, versuchen Sie, Ihren Code in tatsächlichen Scala, nicht nur syntaktisch, sondern idiomatisch umschreiben. Vermeiden Sie einen veränderbaren Zustand und verwenden Sie funktionale Transformationen. Wenn Sie scala Code schreiben möchten, können Sie sich auch etwas Zeit nehmen, um in die richtige Einstellung zu kommen. Sie werden es schließlich zu schätzen wissen, ich verspreche :)

So etwas vielleicht?

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

Danke. Zugewiesener Stream in einer Variablen. aber es funktioniert immer noch nicht. – developer

+0

Nicht sicher, was Sie mit "immer noch nicht funktioniert" meinen. Der Code, den ich oben geschrieben habe, funktioniert. – Dima

+0

Fehler im Heap-Speicher – developer