Qtの応用 - AWS S3

提供: MochiuWiki : SUSE, EC, PCB

2025年11月21日 (金) 13:20時点におけるWiki (トーク | 投稿記録)による版 (ページの作成:「== 概要 == <br><br> == AWS SDK for C++のインストール == Qtの応用_-_AWS#AWS_SDK_for_C++のインストールのページを参照すること。<br> <br><br> == サンプルコード == 以下の例では、AWS S3へのファイルアップロードとダウンロードを行っている。<br> 全ての設定 (リージョン、バケット名、オブジェクトキー) を任意の設定ファイルから読み込んでいる…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)

概要



AWS SDK for C++のインストール

Qtの応用_-_AWS#AWS_SDK_for_C++のインストールのページを参照すること。


サンプルコード

以下の例では、AWS S3へのファイルアップロードとダウンロードを行っている。
全ての設定 (リージョン、バケット名、オブジェクトキー) を任意の設定ファイルから読み込んでいる。

 # config.iniファイル
 
 [AWS]
 # AWSリージョン (必須)
 region=us-east-1
 
 [S3]
 # S3バケット名 (必須)
 bucket=my-bucket-name
 
 [Upload]
 # アップロード時のS3オブジェクトキー
 object_key=uploads/myfile.txt
 
 # アップロードするローカルファイルのパス
 local_file=/path/to/local/file.txt
 
 [Download]
 # ダウンロードするS3オブジェクトキー
 object_key=downloads/myfile.txt
 
 # ダウンロード先のローカルファイルパス
 local_file=/path/to/save/file.txt


 #include <QCoreApplication>
 #include <QCommandLineParser>
 #include <QSettings>
 #include <QFile>
 #include <QFileInfo>
 #include <QDebug>
 #include <fstream>
 #include <iostream>
 #include <aws/core/Aws.h>
 #include <aws/s3/S3Client.h>
 #include <aws/s3/model/PutObjectRequest.h>
 #include <aws/s3/model/GetObjectRequest.h>
 
 // 設定情報を保持する構造体
 struct S3Config {
    QString region;
    QString bucket;
    QString uploadObjectKey;
    QString uploadLocalFile;
    QString downloadObjectKey;
    QString downloadLocalFile;
 };
 
 // 設定ファイルを読み込む関数
 bool loadConfig(const QString& configPath, S3Config& config)
 {
    QFileInfo fileInfo(configPath);
    if (!fileInfo.exists()) {
       std::cerr << "エラー: 設定ファイルが見つかりません: " << configPath.toStdString() << std::endl;
       return false;
    }
 
    QSettings settings(configPath, QSettings::IniFormat);
    settings.setIniCodec("UTF-8");
 
    // AWS設定
    settings.beginGroup("AWS");
    config.region = settings.value("region").toString();
    settings.endGroup();
 
    // S3設定
    settings.beginGroup("S3");
    config.bucket = settings.value("bucket").toString();
    settings.endGroup();
 
    // アップロード設定
    settings.beginGroup("Upload");
    config.uploadObjectKey = settings.value("object_key").toString();
    config.uploadLocalFile = settings.value("local_file").toString();
    settings.endGroup();
 
    // ダウンロード設定
    settings.beginGroup("Download");
    config.downloadObjectKey = settings.value("object_key").toString();
    config.downloadLocalFile = settings.value("local_file").toString();
    settings.endGroup();
 
    // 必須項目のチェック
    if (config.region.isEmpty()) {
       std::cerr << "エラー: [AWS] region が設定されていません" << std::endl;
       return false;
    }
    if (config.bucket.isEmpty()) {
       std::cerr << "エラー: [S3] bucket が設定されていません" << std::endl;
       return false;
    }
 
    std::cout << "設定ファイル読み込み完了: " << configPath.toStdString() << std::endl;
    std::cout << "  リージョン: " << config.region.toStdString() << std::endl;
    std::cout << "  バケット名: " << config.bucket.toStdString() << std::endl;
 
    return true;
 }
 
 class S3Manager {
 private:
    std::unique_ptr<Aws::S3::S3Client> m_s3Client;
 
 public:
    S3Manager(const QString& region)
    {
       Aws::Client::ClientConfiguration clientConfig;
       clientConfig.region = region.toStdString();
       m_s3Client = std::make_unique<Aws::S3::S3Client>(clientConfig);
 
       std::cout << "S3クライアント初期化完了 (リージョン: " << region.toStdString() << ")" << std::endl;
    }
 
    bool uploadFile(const QString& bucketName, const QString& objectKey, const QString& filePath)
    {
       std::cout << "\n=== アップロード開始 ===" << std::endl;
       std::cout << "  ローカルファイル: " << filePath.toStdString() << std::endl;
       std::cout << "  S3パス: s3://" << bucketName.toStdString()  << "/" << objectKey.toStdString() << std::endl;
 
       // ファイルの存在チェック
       QFileInfo fileInfo(filePath);
       if (!fileInfo.exists()) {
          std::cerr << "エラー: ファイルが見つかりません: " << filePath.toStdString() << std::endl;
          return false;
       }
 
       Aws::S3::Model::PutObjectRequest request;
       request.SetBucket(bucketName.toStdString());
       request.SetKey(objectKey.toStdString());
 
       // ファイルをストリームとして読み込む
       auto inputData = Aws::MakeShared<Aws::FStream>("PutObjectInputStream", filePath.toStdString().c_str(), std::ios_base::in | std::ios_base::binary);
 
       if (!inputData->is_open()) {
          std::cerr << "エラー: ファイルを開けません: " << filePath.toStdString() << std::endl;
          return false;
       }
 
       request.SetBody(inputData);
       request.SetContentLength(fileInfo.size());
 
       auto outcome = m_s3Client->PutObject(request);
 
       if (outcome.IsSuccess()) {
          std::cout << "✓ アップロード成功!" << std::endl;
          return true;
       }
       else {
          std::cerr << "✗ アップロード失敗: " << outcome.GetError().GetMessage() << std::endl;
          return false;
       }
    }
 
    bool downloadFile(const QString& bucketName, const QString& objectKey, const QString& filePath)
    {
       std::cout << "\n=== ダウンロード開始 ===" << std::endl;
       std::cout << "  S3パス: s3://" << bucketName.toStdString() << "/" << objectKey.toStdString() << std::endl;
       std::cout << "  保存先: " << filePath.toStdString() << std::endl;
 
       Aws::S3::Model::GetObjectRequest request;
       request.SetBucket(bucketName.toStdString());
       request.SetKey(objectKey.toStdString());
 
       auto outcome = m_s3Client->GetObject(request);
 
       if (outcome.IsSuccess()) {
          auto& retrieved_file = outcome.GetResultWithOwnership().GetBody();
 
          std::ofstream output_file(filePath.toStdString(), std::ios::binary);
          if (!output_file.is_open()) {
             std::cerr << "エラー: 保存先ファイルを開けません: " << filePath.toStdString() << std::endl;
             return false;
          }
 
          output_file << retrieved_file.rdbuf();
          output_file.close();
 
          // ファイルサイズを表示
          QFileInfo fileInfo(filePath);
          std::cout << "✓ ダウンロード成功! (サイズ: " << fileInfo.size() << " bytes)" << std::endl;
          return true;
       }
       else {
          std::cerr << "✗ ダウンロード失敗: " << outcome.GetError().GetMessage() << std::endl;
          return false;
       }
    }
 };
 
 int main(int argc, char *argv[])
 {
    QCoreApplication app(argc, argv);
    QCoreApplication::setApplicationName("AWS S3 Manager");
    QCoreApplication::setApplicationVersion("1.0");
 
    // コマンドライン引数のパーサーを設定
    QCommandLineParser parser;
    parser.setApplicationDescription("AWS S3ファイルアップロード・ダウンロードツール (設定ファイルベース)");
    parser.addHelpOption();
    parser.addVersionOption();
 
    // オプション定義
    QCommandLineOption uploadOption(QStringList() << "u" << "upload", "ファイルをアップロード");
    parser.addOption(uploadOption);
 
    QCommandLineOption downloadOption(QStringList() << "d" << "download", "ファイルをダウンロード");
    parser.addOption(downloadOption);
 
    QCommandLineOption configOption(QStringList() << "c" << "config",  "設定ファイルのパス (デフォルト: config.ini)", "config", "config.ini");
    parser.addOption(configOption);
 
    parser.process(app);
 
    // AWS SDKの初期化
    Aws::SDKOptions options;
    Aws::InitAPI(options);
 
    int result = 0;
 
    {
       // 設定ファイルのパスを取得
       QString configPath = parser.value(configOption);
 
       // 設定を読み込む
       S3Config config;
       if (!loadConfig(configPath, config)) {
          std::cerr << "\n設定ファイルの例:" << std::endl;
          std::cerr << "  [AWS]" << std::endl;
          std::cerr << "  region=ap-northeast-1" << std::endl;
          std::cerr << "  " << std::endl;
          std::cerr << "  [S3]" << std::endl;
          std::cerr << "  bucket=my-bucket-name" << std::endl;
          std::cerr << "  " << std::endl;
          std::cerr << "  [Upload]" << std::endl;
          std::cerr << "  object_key=folder/myfile.txt" << std::endl;
          std::cerr << "  local_file=/path/to/local/file.txt" << std::endl;
          std::cerr << "  " << std::endl;
          std::cerr << "  [Download]" << std::endl;
          std::cerr << "  object_key=folder/myfile.txt" << std::endl;
          std::cerr << "  local_file=/path/to/save/file.txt" << std::endl;
          Aws::ShutdownAPI(options);
          return 1;
       }
 
       // S3マネージャーを初期化
       S3Manager s3Manager(config.region);
 
       if (parser.isSet(uploadOption)) {
          // アップロード
          if (config.uploadObjectKey.isEmpty() || config.uploadLocalFile.isEmpty()) {
             std::cerr << "エラー: [Upload] セクションに object_key と local_file が必要です" << std::endl;
             result = 1;
          }
          else {
             if (!s3Manager.uploadFile(config.bucket, config.uploadObjectKey, config.uploadLocalFile)) {
                result = 1;
             }
          }
       }
       else if (parser.isSet(downloadOption)) {
          // ダウンロード
          if (config.downloadObjectKey.isEmpty() || config.downloadLocalFile.isEmpty()) {
             std::cerr << "エラー: [Download] セクションに object_key と local_file が必要です" << std::endl;
             result = 1;
          }
          else {
             if (!s3Manager.downloadFile(config.bucket, config.downloadObjectKey, config.downloadLocalFile)) {
                result = 1;
             }
          }
       }
       else {
          std::cerr << "エラー: --upload または --download を指定してください" << std::endl;
          parser.showHelp(1);
       }
    }
 
    // AWS SDKのクリーンアップ
    Aws::ShutdownAPI(options);
 
    return result;
 }