JavaでS3に読み書きする方法

javaのspring bootでs3にファイルをアップロード、ダウンロードする方法を紹介します。
書き出したい文字列をファイルにアップロードするのと、s3にあるファイルを文字列として読み込む方法です。
ローカルにあるファイルをアップロードしたり、ファイル形式でダウンロードするわけではないので、注意してください。


Mavenの設定

sdk全てをダウンロードすると時間がかかるので、s3のみを使用したい場合はsdk-s3としましょう。

<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 -->
<dependency>
    <groupId>com.amazonaws</groupId
    <artifactId>aws-java-sdk-s3</artifactId
    <version>1.11.327</version>
</dependency>


s3ClientConfigクラス

s3Clientを使うためには、regionやbucketの名前などの設定が必要で、それをするためのクラスです。

@Configuration
public class S3ClientConfig {

    @Value("${cloud.aws.region.static}")
    private String s3ClientRegion;

    @Value("${aws.bucketName}")
    private String s3BucketName;

    @Value("${cloud.aws.credentials.access-key}")
    private String accessKey;

    @Value("${cloud.aws.credentials.secret-key}")
    private String secretKey;

    private AWSCredentials credentials;


    @PostConstruct
    public void init() {
        credentials = new BasicAWSCredentials(accessKey, secretKey);
    }

    @Bean
    AmazonS3 s3Client() {
        return  AmazonS3ClientBuilder
                .standard()
                .withRegion(s3ClientRegion)
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .build();
    }
}

@Valueで、application.propertiesファイルから必要な情報を持ってきています。


読み書きを実装するクラス
@Service
public class S3Manager {

    @Value("${aws.bucketName}")
    private String s3BucketName;

    @Resource
    private AmazonS3 s3Client;

    private static Logger logger = LoggerFactory.getLogger(S3Manager.class);


    public String createFile(String objectKey, String string) {   //(1)

        s3Client.putObject(s3BucketName, objectKey, string);

        return objectKey;

    }

    public String createCsvFile(String objectKey, List<String> lines) {  //(2)
        StringBuilder sb = new StringBuilder();
        for (String line : lines) {
            sb.append(line);
            sb.append(",");
            sb.append("\n");
        }

        s3Client.putObject(s3BucketName, objectKey, sb.toString());

        return objectKey;
    }

    public String readFile(String objectKey)  {  //(3)

        if (!s3Client.doesObjectExist(s3BucketName, objectKey)) {  //(4)
            return null;
        }
        try {
            //s3objectを取得
            S3Object o = s3Client.getObject(s3BucketName, objectKey);
            S3ObjectInputStream s3is = o.getObjectContent();     //(5)
            BufferedReader br = new BufferedReader(new InputStreamReader(s3is));
            // 読み込んだ文字列を保持するストリングバッファを用意します。
            StringBuilder sb = new StringBuilder();
            // ファイルから読み込んだ一文字を保存する変数です。
            int c;
            // ファイルから1文字ずつ読み込み、バッファへ追加します。
            while ((c = br.read()) != -1) {
                sb.append((char) c);
            }
            // バッファの内容を文字列化して返します。
            br.close();
            return sb.toString();

        } catch (IOException e) {
            logger.error("error while reading file", e);
            return null;
        }

}


(1) createFileは、s3内に新しくファイルをアップロードするメソッドで引数の文字列(string)がそのままファイルになります。
objectKeyは、ファイルのkeyとなるもので、s3Client.putObjectでs3にファイルを保存する際に必要です。

(2) どんな文字列もアップロードできます。ここではcsv形式のファイルをアップロードしています。

(3) readFileメソッドは指定のobjectKeyのファイルを文字列で読み込むメソッドです。

(4)指定のkeyがこのbucketに存在するか判定しています。

(5) ファイルの中身をstream形式で読み込み、最終的に文字列にしています。


以上がs3にファイルを文字列で読み書きする方法です。
一度読み込み、文字列を追加したり消去して再度アップロードすれば簡単にs3内のファイルも編集できます。

使い方など詳しく書かれた公式のドキュメントがあるのでそれも参考にしてみてください。

https://docs.aws.amazon.com/ja_jp/sdk-for-java/v2/developer-guide/aws-sdk-java-dg.pdf