簡體   English   中英

spring批處理文件寫入器直接寫入亞馬遜s3存儲而無需PutObjectRequest

[英]spring batch file writer to write directly to amazon s3 storage without PutObjectRequest

我正在嘗試將文件上傳到亞馬遜 s3。 我不想上傳,而是想使用 spring 批處理從數據庫中讀取數據並將文件直接寫入 s3 存儲。 無論如何我們可以做到嗎?

Spring Cloud AWS 添加了對 Amazon S3 服務的支持,以使用資源加載器和 s3 協議加載和寫入資源。 配置 AWS 資源加載器后,您可以編寫自定義 Spring Batch 編寫,例如:

import java.io.OutputStream;
import java.util.List;

import org.springframework.batch.item.ItemWriter;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.WritableResource;

public class AwsS3ItemWriter implements ItemWriter<String> {

    private ResourceLoader resourceLoader;

    private WritableResource resource;

    public AwsS3ItemWriter(ResourceLoader resourceLoader, String resource) {
        this.resourceLoader = resourceLoader;
        this.resource = (WritableResource) this.resourceLoader.getResource(resource);
    }

    @Override
    public void write(List<? extends String> items) throws Exception {
        try (OutputStream outputStream = resource.getOutputStream()) {
            for (String item : items) {
                outputStream.write(item.getBytes());
            }
        }
    }
}

然后,您應該能夠將此s3://myBucket/myFile.log與 S3 資源一起使用,例如s3://myBucket/myFile.log

無論如何我們可以做到嗎?

請注意,我沒有編譯/測試之前的代碼。 我只是想給你一個如何去做的起點。

希望這可以幫助。

問題是OutputStream只會寫入步驟發送的最后一個List 項目...我認為您可能需要在文件系統上寫入一個臨時文件,然后將整個文件發送到單獨的 tasklet 中

請參閱此示例: https : //github.com/TerrenceMiao/AWS/blob/master/dynamodb-java/src/main/java/org/paradise/microservice/userpreference/service/writer/CSVFileWriter.java

我也有同樣的事情要做。 因為 spring 沒有單獨寫入流的類,所以我像上面的例子一樣創建了一個自己:

你需要為此上課。 一個實現 WriteableResource 並擴展 AbstractResource 的 Resource 類:

...

public class S3Resource extends AbstractResource implements WritableResource {

   ByteArrayOutputStream resource = new ByteArrayOutputStream();

    @Override
    public String getDescription() {
        return null;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(resource.toByteArray());
    }

    @Override
    public OutputStream getOutputStream() throws IOException {
        return resource;
    }
}

以及您擴展 ItemWriter 的作家:

public class AmazonStreamWriter<T> implements ItemWriter<T>{

    private WritableResource resource;
    private LineAggregator<T> lineAggregator;
    private String lineSeparator;

    public String getLineSeparator() {
        return lineSeparator;
    }

    public void setLineSeparator(String lineSeparator) {
        this.lineSeparator = lineSeparator;
    }

    AmazonStreamWriter(WritableResource resource){
        this.resource = resource;
    }

    public WritableResource getResource() {
        return resource;
    }

    public void setResource(WritableResource resource) {
        this.resource = resource;
    }

    public LineAggregator<T> getLineAggregator() {
        return lineAggregator;
    }

    public void setLineAggregator(LineAggregator<T> lineAggregator) {
        this.lineAggregator = lineAggregator;
    }

    @Override
    public void write(List<? extends T> items) throws Exception {
        try (OutputStream outputStream = resource.getOutputStream()) {
                StringBuilder lines = new StringBuilder();
                Iterator var3 = items.iterator();

                while(var3.hasNext()) {
                    T item = (T) var3.next();
lines.append(this.lineAggregator.aggregate(item)).append(this.lineSeparator);
                }
                outputStream.write(lines.toString().getBytes());
        }
    }
}

通過此設置,您將編寫從數據庫收到的項目信息,並通過 OutputStream 將其寫入您的 Customresource。 然后可以在您的步驟之一中使用填充的資源 zu 打開 InputStream 並通過客戶端上傳到 S3。 我做到了: amazonS3.putObject(awsBucketName, awsBucketKey , resource.getInputStream(), new ObjectMetadata());

我的解決方案可能不是完美的方法,但從這里開始您可以對其進行優化。

我不確定您是否可以直接在S3資源上寫...目前,只有讀訪問權限可用。 您可能會通過S3客戶端上傳文件或輸出流,因此必須使用臨時文件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM