2023年6月19日

【Google Cloud】Javaを使ってCloud Storageへフォルダをアップロードする方法


Content
こんにちは、うましです!
今回はCloud Storageへのフォルダのアップロード方法について解説します!
ファイルのアップロード方法は解説記事であふれていますが、
フォルダの構造を保持したままアップロードする方法は少なく、私自身苦戦したので、皆さまのご参考になれば嬉しいです!

前提

・ファイルシステムからCloud Storageにフォルダをアップロードする

・フォルダ構造を保持したままアップロードする

・使用環境:Java1.8.0、Spring

Cloud Storageの準備:Bucket作成

まずは、Cloud Storageの準備です。
Cloud Storageは「Bucket(バケット)」と呼ばれる箱にデータを出し入れできるサービスです。
では、早速Bucketを作っていきましょう。



1.Cloud Storage > バケットの画面から「+作成」ボタンを押下

 

2.必要事項を入力し「作成」ボタンを押下
※本記事のメインではないため詳細は割愛します。

Cloud Storageの準備:アクセス権 設定

Cloud Storageへのアクセス権を付与します。

本来は、バケットごとへの権限付与や制限をする必要がありますが、

今回は細かいことは一旦忘れてサービスアカウントのアクセスキーを使用します。

1.サービスアカウントの鍵を作成

2.JSONキーを選択し、作成

3.JSONキーをローカルへ保存

※このJSONファイルを使用してCloud Storageへのアクセス認証を行います

Javaでアップロードの実装

では、準備が長かったですが本題のフォルダアップロードに入ります。
以下のような構造のフォルダを例にアップロードします。
hoge1
 └-- hoge1.txt
 └-- hoge2
      └-- hoge2.txt

ざっくりですが、以下の流れで構造を保ったままフォルダをアップロードすることができました。

  1. ブラウザからMultipartFile形式でフォルダを受け取る
  2. サービスアカウントファイルを使用して認証する
  3. MultipartFileをFor文でファイル1つずつアップロード処理を実行

(ファイル1つずつアップロードするならFor文だろ、、なんで苦戦したんだ、、というつっこみは内に留めておいてください。。)


// 変数を宣言
String serviceAccountPath = [JSONファイルのパス];
String bucketName = [アップロード先のバケット名];


// 1.ブラウザからMultipartFile形式でフォルダを受け取る
public static void uploadObject(String serviceAccountPath, List<MultipartFile> multiFiles, String bucketName){


    // 2.サービスアカウントファイルを使用して認証する
    Storage storage = StorageOptions.newBuilder().setCredentials(
                ServiceAccountCredentials.fromStream(
                    new FileInputStream(serviceAccountPath)))
                        .build().getService();


    // 3.MultipartFileをFor文でファイル1つずつアップロード処理を実行
    for(MultipartFile multiFile : multiFiles){


        // 4.アップロード処理を実行
        // マルチパートファイルからinputstreamを取得する
        InputStream inputStream = multiFile.getInputStream();


        // アップロードするファイル名を取得する
        String fileName = multiFile.getOriginalFilename();


        // バケット名とファイル名からBlobInfoを作成する
        BlobInfo blobInfo = BlobInfo.newBuilder(bucketName, fileName).build();


        // WriteChannelをストレージとBlobInfoから作成する
        WriteChannel uploadWriter = storage.writer(blobInfo);


        // アップするデータを細切れにして書き込む
        byte[] buffer = new byte[10 * 1024 * 1024];
        int limit;


        while ((limit = inputStream.read(buffer)) >= 0){
            ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, limit);
            // BlobInfoへinputstreamのコンテンツを書き込む
            uploadWriter.write(byteBuffer);
        }
    }
}

※このままだとメモリが開かれっぱなしなので適宜close()を入れましょう

動作確認

では動かしていきましょう。

作成したバケットにアップロードされていますね!

フォルダ構成も保持されているのがわかります!

参考:Cloud Storageにおけるフォルダとは

上記のように、コンソール上で確認するとフォルダ構造が保持されて見えますが、
Cloud Storageでは、実はフォルダという概念は存在しません。
hoge1
 └-- hoge1.txt
 └-- hoge2
      └-- hoge2.txt

バケットの中に、2つのオブジェクトが存在するだけです。
hoge1というフォルダは存在せず、文字列「hoge1」がオブジェクト名の一部になるだけです。
hoge1/hoge1.txt
hoge1/hoge2/hoge2.txt

なので、MultipartFileをfor文で回すだけで、フォルダ構造を維持してアップロードできるんですね!

 

ここで注意なのが、オブジェクトとして判定されないため下図のhoge3はアップされないということです。
hoge1
 └-- hoge1.txt
 └-- hoge2
      └-- hoge2.txt
 └-- hoge3

今回はフォルダ構造を保持したままフォルダをアップロードする方法について紹介しました。
いかがでしたでしょうか?
参考になった!わかりにくい!などご感想いただけると嬉しいです!

当社、システムサポートは、Google Cloudの導入・移行・運営支援を行っています。
お手持ちのデータのGoogle Cloud BigQuery移行、データの可視化のご相談は、以下よりお願いいたします。

Google Cloud導入についてのお問い合わせはこちら

2023年6月19日 【Google Cloud】Javaを使ってCloud Storageへフォルダをアップロードする方法

Category Google Cloud

ご意見・ご相談・料金のお見積もりなど、
お気軽にお問い合わせください。

お問い合わせはこちら