首頁

目前文章總數:190 篇

  

最後更新:2025年 07月 26日

0097. Google Cloud Storage 與 C# 整合:憑證設定與檔案操作實例

日期:2025年 08月 16日

標籤: Asp.NET Core Windows Forms Google Cloud Platform Google Cloud Storage

摘要:C# 學習筆記


範例所需: 1. Visual Studio 2022 Asp.net Core
      2. 已開通 Google
範例檔案:本篇範例代碼
相關參考:Google Cloud 首頁
解決問題:啟用 Google Cloud Storage 與 檔案伺服器、並且用 C# WinForm 實現上傳、下載功能
基本介紹:本篇分為五大部分。
第一部分:Google Cloud Storage 簡介
第二部分:開通與設定 Google Cloud Storage
第三部分:上傳檔案到 CGS - DEMO
第四部分:下載檔案從 CGS - DEMO
第五部分:公開訪問 Bukcet 設定 - DEMO






第一部分:Google Cloud Storage 簡介

Step 1: Google Cloud Storage (GCS) 介紹

以下擷取自 Google Cloud Storage 的功能介紹

各種規模企業均適用的物件儲存空間
Cloud Storage 是一項代管服務,用於儲存非結構化資料。 無論多少資料都能存放,還能任意擷取。


透過 Google 雲提供的 GCS 可以存儲檔案,建立網路硬碟空間

Step 2: 物件存儲架構差異 - 特色

Google Cloud 的物件存儲空間解釋
主要有 3 種, GCS 使用的是 Object Storage(物件儲存)
各自的特點如下:

項目 檔案儲存(File Storage) 區塊儲存(Block Storage) 物件儲存(Object Storage)
類似概念 網路共享磁碟(NAS) 硬碟分割區、磁區(SAN) 雲端的資料倉庫
存取方式 路徑 + 檔名(類似 C:\file.txt) OS/程式透過磁區位址 URL 或 Object Key
資料結構 檔案/資料夾階層結構 原始區塊(無檔案概念) Key-Value + Metadata
支援操作 檔案開啟/編輯/掛載 作業系統當磁碟操作 PUT / GET / DELETE
適合用途 檔案共享、多人編輯、舊系統遷移 VM 系統碟、資料庫磁碟 圖片、影片、備份、靜態網站
GCP 代表服務 Filestore Persistent Disk Google Cloud Storage (GCS)


Step 3:物件存儲架構差異 - 優點、缺點

GCS 採用物件儲存(Object Storage),適合存讀的場合,因此適合使用,若要編輯檔案則是檔案儲存(File Storage)較為合適。
相對的,使用 GCS 時,只能對物件做刪除,並請再次上傳檔案,不能直接編輯檔案

項目 檔案儲存(File Storage) 區塊儲存(Block Storage) 物件儲存(Object Storage)
存取情境 日常檔案存取(如開發資料夾、共用檔案) 快速大量小區塊 I/O(如資料庫) 雲讀多寫少、大檔、低頻(如圖片、影片)
優點 類似本機檔案系統,開發容易 效能最好,適合高頻隨機讀寫。 可儲存龐大數量的檔案,橫向擴展性高。
  適合資料夾結構的應用。 可當成虛擬硬碟掛載給 VM 適合靜態網站、備份、影片、圖片等。
缺點 不易橫向擴展(scale-out)。 不具檔案或結構概念,需要 OS 層組織檔案系統。 不支援像本機磁碟一樣隨機讀寫(非即時修改)。
  額外存儲檔案資訊 使用較複雜,不適合直接物件儲存。 不能「修改檔案的一部分」,只能重新上傳整個物件。


File / Object Storage 是建立在 Block Storage 上的架構

Step 4: GCS 儲存空間方案 & 收費

詳細的 CGS 會因為儲存類型區域 而收費有所不同,以下是 4 種儲存類型差異
官方詳細說明

儲存類型 適用情境 最低儲存時間 存取頻率 成本 (相對)
Standard 經常存取(熱資料) 最高
Nearline 偶爾存取(如每月一次) 30 天 中低
Coldline 很少存取(如季或年存取一次) 90 天
Archive 幾乎不會存取(長期備份) 365 天 極低 最便宜


其中 最低儲存時間 表示時間到時,會進行刪除,並酌收一次費用,若在最低儲存時間前刪除,也會酌收一次費用
因此 Archive 之所以最便宜是因為用於備份,資料 365 天後自動刪除時,才收一次費用

第二部分:開通與設定 Google Cloud Storage

Step 1: 建立GCS - 登入 GCP

為了要能從程式上傳檔案到 GCS ,需要先啟用 GCS 與設定相關權限,依序執行:
登入 Google Cloud Platform -> 選擇 Cloud Storage -> 選擇 Bucket

Step 2: 建立GCS - 開始作業

要設定 BucketName 必須要全域不重複的名稱

Step 3: 建立GCS - 位置類型

位置類型有 Multi-region、Dual-region、Region 三種類型,若要全球通用可以選擇 Multi-region
但這篇是為了說明如何上傳、下載 GCS 存儲,因此選擇 Region

Step 4: 建立GCS - 資料存儲方式

資料存儲方式,因為說明的關係,需要即時更新、反覆刪除、上傳、下載,因此選擇 Standard

Step 5: 建立GCS - 控制物件存取權

這邊選擇統一、讓設定先趨於簡單,統一 Bucket 物件權限

Step 6: 建立GCS - 保護物件資料方式

使用資料加密 -> Google 代管的加密金鑰
便於後續我們設定金鑰後可以讓程式使用金鑰存取 GCS

Step 7: 建立GCS - 建立完成

建立完成後,可以看到 Bucket 已建立成功,但目前還需設定金鑰才可透過程式上傳、下載

Step 8: 建立服務帳戶 - 選擇 GCP 列表

設定金鑰前,還需給 GCS 設定服務帳戶,才能設定 GCS金鑰
請選擇左上角設定

Step 9: 建立服務帳戶 - 選擇服務帳戶

IAM 與管理 -> 服務帳戶

Step 10: 建立服務帳戶 - 建立服務與帳戶

選擇建立服務與帳戶

選擇後,在如圖的地方設定相關名稱、ID、說明

Step 11: 建立服務帳戶 - 權限

請選擇角色的地方,找到 Cloud Storage -> 給予 Storage 管理員權限,此為我們開發者自己使用

Step 12: 建立服務帳戶 - 完成

選擇完成,建立成功

Step 13: 建立金鑰 - 選擇已建立帳戶

選擇剛剛已建立的帳戶

Step 14: 建立金鑰 - 產生Json

金鑰索引鍵選擇 Json -> 建立

Step 15: 建立金鑰 - 完成

將產生的 Json 檔案,藉由程式讀取或者 Hardcode 寫死在程式中使用(不建議這樣做,進入版控後有可能被他人知道,此篇因為要舉例說明,因此 HardCode)
請將此金鑰複製,後續程式會使用



第三部分:上傳檔案到 MinIO - DEMO

Step 1: 基本參數設定

可下載本篇範例代碼
進入主程式後,預設會有以下配置

_BucketName 對應 GCS BucketName
_GCS_Crendential_Json 第二部分 Step 15. 產生的 Json 直接貼上(不建議,目前範例說明因此使用此方法)
        private readonly string _BucketName = $@"milkteagreenstorage";
        private readonly string _GCS_Crendential_Json = $@"
  您的Json
";


Step 2: 安裝相依套件

接著專案 -> Nuget 套件管理員 -> 輸入 Google.Cloud.Storage.V1
進行安裝此 SDK

Step 3: 選擇上傳檔案的按鈕

點擊按鈕時,選擇自己本機要上傳的檔案用

/// <summary>
/// 1. 選擇上傳的檔案
/// </summary>
private void GCS_browse_button_Click(object sender, EventArgs e)
{
    using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.InitialDirectory = "c:\\";
                openFileDialog.Filter = "All files (*.*)|*.*";
                openFileDialog.FilterIndex = 1;
                openFileDialog.RestoreDirectory = true;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    // 獲取選取的檔案路徑
                    GCS_textBox_filepath.Text = openFileDialog.FileName;
                }
            }
}


Step 4: 執行上傳檔案的按鈕

執行上傳時,會引入金鑰的 Json 檔案,並且建立 Credential,將選擇上傳的檔案,上傳到 GCS

/// <summary>
/// 2. 執行上傳
/// </summary>
private void GCS_uploadFile_button_Click(object sender, EventArgs e)
        {
            _ = Task.Run(() => Working());

            async Task Working()
            {

                try
                {
                    var credential = GoogleCredential.FromJson(_GCS_Crendential_Json);
                    var storage = StorageClient.Create(credential);

                    // 上傳一個檔案
                    string filePath = GCS_textBox_filepath.Text;
                    string objectName = Path.GetFileName(filePath);
                    using (var fileStream = new FileStream(filePath, FileMode.Open))
                    {
                        storage.UploadObject(_BucketName, objectName, null, fileStream);
                    }
                    await ShowMessageAsync("上傳成功!");
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Exception: {e}");
                }
            }
        }


Step 5: DEMO - 選擇上傳檔案

如圖,我們執行專案後,選擇檔案 -> 並且選擇本機的 GCS_Upload_MilkTeaGreen_File.txt 檔案

Step 6: DEMO - 執行上傳

如圖,執行上傳,並提示成功

Step 7: DEMO - 成功

回到 GCS 上檢查,可以發現檔案已經成功上傳了



第四部分:下載檔案從 MinIO - DEMO

Step 1: 選擇下載存放的按鈕

點擊按鈕時,選擇從 GCS 下載時,本機要存放此檔案的位置

/// <summary>
/// 3. 選擇下載的檔案存放位置
/// </summary>
private void GCS_downloadPath_Button_Click(object sender, EventArgs e)
 {
     using (FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog())
     {
         folderBrowserDialog.Description = "選擇下載檔案的資料夾";
         folderBrowserDialog.ShowNewFolderButton = true; // 是否允許建立新資料夾
         if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
         {
             // 獲取選取的資料夾路徑
             string selectedFolderPath = folderBrowserDialog.SelectedPath;
             GCS_textBox_downloadPathFile.Text = selectedFolderPath; // 在文本框中顯示選取的資料夾路徑
         }
     }
 }


Step 2: 執行下載檔案的按鈕

執行下載時,一樣需要引入金鑰的 Json 檔案,並且建立 Credential
並且依照輸入的檔案名稱,從 GCS 將對應 Bucket 內的此檔案下載到本機存放位置

/// <summary>
/// 4. 執行下載
/// </summary>
private void GCS_download_Button_Click(object sender, EventArgs e)
{
    _ = Task.Run(() => Working());

    async Task Working()
            {
                try
                {
                    var credential = GoogleCredential.FromJson(_GCS_Crendential_Json);
                    var storage = StorageClient.Create(credential);

                    // 下載一個檔案
                    string objectName = GCS_Download_FileNameTextBox.Text;
                    string downloadFilePath = GCS_textBox_downloadPathFile.Text + "\\" + objectName;
                    using (var outputFile = File.OpenWrite(downloadFilePath))
                    {
                        storage.DownloadObject(_BucketName, objectName, outputFile);
                    }
                    await ShowMessageAsync("下載成功!");
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Exception: {e}");
                }
            }
}


Step 3: DEMO - 選擇下載檔案存放位置

如圖,輸入要下載的檔案名稱,並且選擇存放位置

Step 4: DEMO - 執行下載

如圖,執行下載,並提示成功

Step 5: DEMO - 成功

檢查本機的對應目錄,可以看到從 GCS 上下載了此檔案



第五部分:公開訪問 Bukcet 設定 - DEMO

Step 1: 描述問題 - 當前圖檔無法提供檢視

目前我們上傳了一張早安2.png 的圖片在 GCS 上


圖片預期畫面:


開啟無痕 -> 將公開檢視此圖的 URL 貼上網址列
會出現 Access denied. ,這時需要開啟權限,才能在網路上提供公開檢視

Step 2: 開放公開檢視權限 - 登入 GCS Bucket

登入 GCS -> 選擇 Bucket -> 權限 -> 按照主體查看 -> 選擇授予存取權

Step 3: 開放公開檢視權限 - 新增主體

新增主體輸入 : allUsers
角色選擇 : Storage 檢視者

Step 4: 開放公開檢視權限 - 允許資源公開

允許存取公開,讓此 Bucket 內的圖片提供檢視
※如果您的產品有屬於身分證、用戶個人資料、機密資料,應新建另一個 Bucket 與公開的 Bucket 分開使用

Step 5: 開放公開檢視權限 - 設定完成

設定完成後,可以觀察到此 Bucket 的公開存取權已變為在網際網路上公開

Step 6: 開放公開檢視權限 - Demo 成功

再回到此圖片 早安2.png,並且用無痕檢視公開網址,可以看到權限已開通,可以在網際網路上看到此圖片