it-swarm.com.de

So legen Sie die Länge des InputStream-Inhalts fest

Ich lade Dateien in den Amazon S3-Bucket hoch. Die Dateien werden hochgeladen, aber ich erhalte die folgende Warnung. 

WARNUNG: Keine Inhaltslänge für Streamdaten angegeben. Stream Inhalte werden im Speicher zwischengespeichert und können zu Speicherfehlern führen.

Also fügte ich meinem Code die folgende Zeile hinzu

metaData.setContentLength(IOUtils.toByteArray(input).length);

aber dann bekam ich die folgende meldung. Ich weiß nicht mal, ob es eine Warnung ist oder was. 

Das Lesen von Daten hat eine andere Länge als erwartet: dataLength = 0; erwartete Länge = 111992; includeSkipped = falsch; in.getClass () = Klasse Sun.net.httpserver.FixedLengthInputStream; markedSupported = false; markiert = 0; resetSinceLastMarked = false; markCount = 0; resetCount = 0

Wie kann ich contentLength auf die Metadaten von InputSteam setzen? Jede Hilfe wäre sehr dankbar.

13
Shaonline

Wenn Sie die Daten mit IOUtils.toByteArray lesen, verbraucht dies den InputStream. Wenn die AWS-API versucht, sie zu lesen, ist sie null.

Lesen Sie den Inhalt in ein Byte-Array und stellen Sie einen InputStream bereit, der dieses Array mit der API umgibt:

byte[] bytes = IOUtils.toByteArray(input);
metaData.setContentLength(bytes.length);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, byteArrayInputStream, metadata);
client.putObject(putObjectRequest);
20
ataylor

Aktuelle Nachrichten! AWS SDK 2.0 bietet integrierte Unterstützung für das Hochladen von Dateien:

        s3client.putObject(
                (builder) -> builder.bucket(myBucket).key(file.getName()),
                RequestBody.fromFile(file)
        );

Es gibt auch RequestBody Methoden, um Strings oder Puffer zu nehmen, die Content-Length automatisch und effizient einstellen. Nur wenn Sie über eine andere Art von InputStream verfügen, müssen Sie die Länge noch selbst angeben - allerdings sollte dieser Fall bei allen anderen verfügbaren Optionen jetzt seltener sein.

0

Beachten Sie, dass Sie mit einem ByteBuffer einfach manuell tun, was das AWS SDK bereits automatisch für Sie getan hat! Es puffert immer noch den gesamten Stream in den Speicher und ist so gut wie die ursprüngliche Lösung, die die Warnung des SDK erzeugt.

Sie können das Speicherproblem nur beseitigen, wenn Sie die Länge des Streams auf andere Weise kennen, beispielsweise wenn Sie den Stream aus einer Datei erstellen:

void uploadFile(String bucketName, File file) {
    try (final InputStream stream = new FileInputStream(file)) {
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentLength(file.length());
        s3client.putObject(
                new PutObjectRequest(bucketName, file.getName(), stream, metadata)
        );
    }
}
0