2022/08/20

[Rust]Google Cloud Storageを利用する

rustgcp

概要

Google Cloud Storageにファイルを保存/Google Cloud Storageからファイルを取得する方法をRustで実装しました。

また、GCSにあるファイルを公開するやり方も実装しました。

実装方法

cloud-storage - crates.io: Rust Package Registryを利用しています。

Cargo.tomlでの依存関係の指定

[dependencies]
cloud-storage = { version = "0.11.0", features = ["global-client"] }  // これ
tokio = { version = "1", features = ["full"] }
tokio-util = { version = "0.7", features = ["full"] }
futures = "0.3"
futures-util = { version = "0.3", features = ["alloc"] }

またストレージ管理者のロールが付与されたサービスアカウントを事前に作成して、json形式の秘密鍵を作成し、
そのファイルの絶対パスをGOOGLE_APPLICATION_CREDENTIALSという環境変数に設定しておきます。

ローカルのファイルを指定してGCSにファイルを保存

    use cloud_storage::Client;
    use std::path::PathBuf;
    use tokio::fs::File;

    let local_filepath = PathBuf::from("/path/to/your/file.txt");
    let bucket_name = "your-gcs-bucket-name";
    let filename = "/gcs/object/key.txt";
    let mime_type = "plain/text";

    let client = Client::default();
    let file = File::open(&local_filepath).await?;
    let stream = tokio_util::io::ReaderStream::new(file);
    let _object = client
        .object()
        .create_streamed(
            bucket_name,
            stream,
            None,
            filename,
            mime_type,
        )
        .await?;

メモリ上のバイト配列からGCSにファイルを保存

    use cloud_storage::Client;

    let data = b"This is test".to_vec();
    let bucket_name = "your-gcs-bucket-name";
    let filename = "/gcs/object/key.txt";
    let mime_type = "plain/text";

    let client = Client::default();
    let _object = client
        .object()
        .create(
            bucket_name,
            data,
            filename,
            mime_type,
        )
        .await?;

GCSのファイルを公開

    use cloud_storage::default_object_access_control::Role;
    use cloud_storage::object_access_control::{Entity, NewObjectAccessControl, ObjectAccessControl};

    let bucket_name = "your-gcs-bucket-name";
    let filename = "/gcs/object/key.txt";

    let new_object_access_control = NewObjectAccessControl {
        entity: Entity::AllUsers,
        role: Role::Reader,
    };
    let _acl_item = ObjectAccessControl::create(bucket_name, filename, &new_object_access_control).await?;

GCSからファイルをダウンロードしてローカルに保存

    use cloud_storage::Client;
    use futures::{Stream, StreamExt};
    use std::io::{BufWriter, Write};
    use std::path::PathBuf;

    // /path/to/your/download_dir/gcs/object/key.txt にファイルがダウンロードされます。
    let download_dir = PathBuf::from("/path/to/your/download_dir");
    let bucket_name = "your-gcs-bucket-name";
    let filename = "/gcs/object/key.txt";

    let client = Client::default();
    let mut stream = client
        .object()
        .download_streamed(bucket_name, filename)
        .await?;
    let download_filepath = download_dir.join(filename);
    let mut file = BufWriter::new(std::fs::File::create(&download_filepath).unwrap());
    while let Some(byte) = stream.next().await {
        file.write_all(&[byte.unwrap()]).unwrap();
    }

GCSのファイルを読み込んでstremを取得

    use cloud_storage::Client;
    use futures::{Stream, StreamExt};

    let bucket_name = "your-gcs-bucket-name";
    let filename = "/gcs/object/key.txt";

    let client = Client::default();
    let stream = client
        .object()
        .download_streamed(bucket_name, filename)
        .await?;

その他

こちらのgithubリポジトリにGCSやNFSをファイルストレージとして扱えるようにしたラッパーを開発しています。

google_could_storage.rsのファイルが参考になるかと思います。

以上です。