Java многочастная загрузка на s3 - PullRequest
0 голосов
/ 10 января 2019

Мой метод получает буферизованную программу чтения и преобразует каждую строку в моем файле. Однако мне нужно загрузить вывод этого преобразования в корзину s3. Файлы довольно большие, поэтому я хотел бы иметь возможность передавать свою загрузку в объект s3.

Чтобы сделать это, я думаю, что мне нужно использовать многочастную загрузку, однако я не уверен, что я использую это правильно, так как кажется, что ничего не загружается.

Вот мой метод:

public void transform(BufferedReader reader)
{
        Scanner scanner = new Scanner(reader);
        String row;
        List<PartETag> partETags = new ArrayList<>();

        InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest("output-bucket", "test.log");
        InitiateMultipartUploadResult result = amazonS3.initiateMultipartUpload(request);

        while (scanner.hasNext()) {
            row = scanner.nextLine();

            InputStream inputStream = new ByteArrayInputStream(row.getBytes(Charset.forName("UTF-8")));

            log.info(result.getUploadId());

            UploadPartRequest uploadRequest = new UploadPartRequest()
                    .withBucketName("output-bucket")
                    .withKey("test.log")
                    .withUploadId(result.getUploadId())
                    .withInputStream(inputStream)
                    .withPartNumber(1)
                    .withPartSize(5 * 1024 * 1024);

            partETags.add(amazonS3.uploadPart(uploadRequest).getPartETag());
        }

        log.info(result.getUploadId());

        CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(
                "output-bucket",
                "test.log",
                result.getUploadId(),
                partETags);

        amazonS3.completeMultipartUpload(compRequest);
}

1 Ответ

0 голосов
/ 10 января 2019

О, понятно. InitiateMultipartUploadRequest необходимо читать из входного потока. Это допустимое ограничение, так как вы можете писать только в выходные потоки в целом.

Возможно, вы слышали, что вы можете скопировать данные из InputStream в ByteArrayOutputStream . Затем возьмите полученный байтовый массив и создайте ByteArrayInputStream . Вы можете передать это на ваш объект запроса. НО: Все данные будут в одном байтовом массиве в определенное время. Поскольку ваш вариант использования касается больших файлов, это не может быть o.k.

Вам нужно создать собственный класс потока ввода, который преобразует исходный поток ввода в другой поток ввода. Это требует от вас работы на уровне байтовых абстракций. Однако он будет предлагать лучшую производительность . Я предлагаю задать новый вопрос, если вы хотите узнать больше об этом.

Ваш код преобразования уже завершен, и вы не хотите снова его трогать? Есть другой подход. Вы также можете просто «подключить» выходной поток к входному потоку, используя pipe : https://howtodoinjava.com/java/io/convert-outputstream-to-inputstream-example/. Подвох: вы имеете дело с многопоточностью здесь.

...