Проблема в вашем внутреннем цикле while. Обычно вы читаете 1024 байта из ZipInputStream и загружаете их в S3. Вместо потоковой передачи в S3 вы будете перезаписывать целевой ключ снова и снова и снова.
Решение этой проблемы несколько сложнее, поскольку у вас нет одного потока на файл, а один поток на контейнер zip. Это означает, что вы не можете сделать что-то подобное ниже, потому что поток будет закрыт AWS после первой загрузки
// Not possible
PutObjectRequest request = new PutObjectRequest(targetBucket, name,
zipInputStream, meta);
Вы должны записать ZipInputStream в объект PipedOutputStream - для каждой из позиций ZipEntry,Ниже приведен рабочий пример
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Pipes {
public static void main(String[] args) throws IOException {
Regions clientRegion = Regions.DEFAULT;
String sourceBucket = "<sourceBucket>";
String key = "<sourceArchive.zip>";
String targetBucket = "<targetBucket>";
PipedOutputStream out = null;
PipedInputStream in = null;
S3Object s3Object = null;
ZipInputStream zipInputStream = null;
try {
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withRegion(clientRegion)
.withCredentials(new ProfileCredentialsProvider())
.build();
TransferManager transferManager = TransferManagerBuilder.standard()
.withS3Client(s3Client)
.build();
System.out.println("Downloading an object");
s3Object = s3Client.getObject(new GetObjectRequest(sourceBucket, key));
zipInputStream = new ZipInputStream(s3Object.getObjectContent());
ZipEntry zipEntry;
while (null != (zipEntry = zipInputStream.getNextEntry())) {
long size = zipEntry.getSize();
String name = zipEntry.getName();
if (zipEntry.isDirectory()) {
System.out.println("Skipping directory " + name);
continue;
}
System.out.printf("Processing ZipEntry %s : %d bytes\n", name, size);
// take the copy of the stream and re-write it to an InputStream
out = new PipedOutputStream();
in = new PipedInputStream(out);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(size);
PutObjectRequest request = new PutObjectRequest(targetBucket, name, in, metadata);
transferManager.upload(request);
long actualSize = copy(zipInputStream, out, 1024);
if (actualSize != size) {
throw new RuntimeException("Filesize of ZipEntry " + name + " is wrong");
}
out.flush();
out.close();
}
} finally {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
if (s3Object != null) {
s3Object.close();
}
if (zipInputStream != null) {
zipInputStream.close();
}
System.exit(0);
}
}
private static long copy(final InputStream input, final OutputStream output, final int buffersize) throws IOException {
if (buffersize < 1) {
throw new IllegalArgumentException("buffersize must be bigger than 0");
}
final byte[] buffer = new byte[buffersize];
int n = 0;
long count=0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
}