上一篇文章,咱們介紹到在實際項目中系統會產生大量的日誌文件,用戶上傳的頭像等等,同時也介紹到能夠使用Azure Blob Storage 來存儲項目中的一些日誌文件,用戶頭像,用戶視頻等等。這個時候,有人就會問到,那我大概明白Blob能夠存放什麼類型的數據了,這個時候就有人問一些問題了html
1,什麼是Blob?git
答 Azure Blob 存儲是非結構化的,它能夠保存的數據類型是沒有任何限制的。如,pdf文檔,json文件,視頻,txt文件等。咱們常見的類型的文件,它通通能夠進行存儲。可是 Blob 不適合須要常常查詢的結構化數據, 好比說項目中使用的,它們具備比內存和本地磁盤更高的延遲,而且沒有可以讓數據庫高效運行查詢的索引功能。可是,blob常常用與數據庫一塊兒用於存儲不可查詢的的數據,例如用戶頭像存儲在Blob中,數據庫中保存對應用戶頭像的Blob名稱或URL(來自微軟官方解釋)github
其實用能夠這麼說,若是項目中有對於的圖片資源,視頻資源,文件等資源,咱們就能夠考慮到將這些數據都存儲在Azure Blob中。今天在文章的後半段咱們將經過一個簡單的 .NET Core Web 程序去操做 Blob 存儲對象。 數據庫
--------------------我是分割線--------------------json
Azure Blob Storage 存儲系列:windows
2,Azure Storage 系列(二) .NET Core Web 項目中操做 Blob 存儲app
3,Azure Storage 系列(三)Blob 參數設置說明async
4,Azure Storage 系列(四)在.Net 上使用Table Storage ide
開始以前咱們看看 Blob 的類型
1,block blob(塊 blob):由不一樣大小的塊構成,在寫入到塊 blob 時,須要將數據上傳到塊並將其提交到 blob。
2,append blob(追加 blob):是專用的塊 blob,它僅支持追加新數據,追加操做很是高效。 追加 blob 很是適用於存儲日誌或寫入流數據等方案。
3,page blob(頁 blob):專用於涉及隨機存取讀寫的方案。 頁 blob 用於存儲 Azure 虛擬機所使用的虛擬硬盤 (VHD) 文件,但它們很是適用於任何涉及到隨機存取的方案。
今天咱們演示的是 block blob相似,實際項目中,咱們是如何進行操做的
找到以前建立好的 「cnbateblogaccount」 Storage Account,點擊圖中圈起來的 「Containers」,進行建立容器
點擊 「 + Container 」,進行建立容器
注意:這裏的容器,咱們能夠理解爲用來存儲對象的容器
Name:「picturecontainer」
Public access level 選擇:「Private(no anonymous access)」(私有的,不容許匿名訪問)
點擊 「Create"
建立完成後,咱們就能夠在當前容器頁面看到本身建立的 」picturecontainer「 信息。
咱們點擊容器進入,嘗試在上傳一張圖片進行測試
點擊 「Select a file」 進行選擇
選擇 「background.jpg」,點擊 "打開"
勾選 「Overwrite if file already exist」(若是文件存儲,就覆蓋)
點擊 「Upload」 進行上傳
咱們能夠看到上傳的圖片文件,而且它的 Blob 類型是 「block blob」
同時,咱們能夠還有在Portal 上進行預覽,編輯操做。
ok,上述操做咱們是在Azure Portal 上進行操做的。接下來咱們經過代碼進行 blob 的增刪查
vs2019 新建 Web 項目
2.1,首先得安裝 Azure.Storage相關的包
NuGet:Azure.Storage.Blobs
咱們建立 BlobExplorerController 控制器
[HttpGet("{BlobName}")] public async Task<IActionResult> GetBlob(string blobName) { var data = await _blobService.GetBlobAsync(blobName); return File(data.Content, data.ContentType); }
2.2,建立 IBlobService 接口,和 BlobService 實現類,新增獲取 Blob 的接口定義和具體實現方法
Task<BlobInfo> GetBlobAsync(string name);
#region 01,獲取Blob,根據blob名稱+async Task<BlobInfo> GetBlobAsync(string name) /// <summary> /// 獲取Blob,根據blob名稱 /// </summary> /// <param name="name">blob名稱</param> /// <returns></returns> public async Task<Azure.Storage.Models.BlobInfo> GetBlobAsync(string name) { var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); var blobClient = containerClient.GetBlobClient(name); var blobDownLoadInfo = await blobClient.DownloadAsync(); return new Azure.Storage.Models.BlobInfo(blobDownLoadInfo.Value.Content, blobDownLoadInfo.Value.ContentType); } #endregion
建立 BlobInfo 返回實體信息
public class BlobInfo { public BlobInfo(Stream content, string contentType) { this.Content = content; this.ContentType = contentType; } public Stream Content { get; set; } public string ContentType { get; set; } }
2.3 配置連接字符串
Azure Portal 中找到建立的 「cnbateaccount」 的Azure Blob Atorage,點擊 「 Setting=> Access key」
複製圖中的 「Connection string」
將數據庫連接字符串配置在項目的 appsettings 配置文件中
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"AzureBlobStorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=cnbateblogaccount;AccountKey=FU01h022mn1JjONp+ta0DAXOO7ThK3dxxxxxxxxxxxxxxxxx891n9nycsTLGZF83nJpGvTIZvO5VCVxxxxxx0wndOOQ==;EndpointSuffix=core.windows.net"
}
2.4,注入 BlobService,BlobServiceClient
services.AddSingleton(x => new BlobServiceClient(Configuration.GetValue<string("AzureBlobStorageConnectionString"))); services.AddSingleton<IBlobSergvice, BlobService>();
Ok,咱們啓動項目進行測試
postman 中輸入 :localhost:9001/Blobs/background.jpg,效果以下圖所示:
瀏覽器訪問:http://localhost:9001/Blobs/background.jpg,效果以下圖所示:
ok,成功,成功獲取到以前在 Portal 上傳的圖片
2.5 ,完善對 Blob 數據的新增,刪除操做
BlobExplorerController 完整代碼
1 [Route("Blobs")] 2 public class BlobExplorerController : Controller 3 { 4 private readonly IBlobSergvice _blobService; 5 6 public BlobExplorerController(IBlobSergvice blobService) 7 { 8 this._blobService = blobService; 9 } 10 11 [HttpGet("{BlobName}")] 12 public async Task<IActionResult> GetBlob(string blobName) 13 { 14 var data = await _blobService.GetBlobAsync(blobName); 15 return File(data.Content, data.ContentType); 16 } 17 18 [HttpGet("BlobsName")] 19 public async Task<IActionResult> ListBlobsName() 20 { 21 return Ok(await _blobService.ListBlobsNameAsync()); 22 } 23 24 [HttpPost("UploadFile")] 25 public async Task<IActionResult> UpLoadFile([FromBody] UploadFileRequest request) 26 { 27 await _blobService.UploadFileBlobAsync(request.FilePath, request.FileName); 28 return Ok(); 29 } 30 31 [HttpPost("UploadContent")] 32 public async Task<IActionResult> UploadContent([FromBody] UpLoadContentRequest request) 33 { 34 await _blobService.UploadContentBlobAsync(request.Content, request.FileName); 35 return Ok(); 36 } 37 38 [HttpDelete("{BlobName}")] 39 public async Task<IActionResult> DaleteFile(string blobName) 40 { 41 await _blobService.DeleteBlobAsync(blobName); 42 return Ok(); 43 } 44 }
IBlobSergvice 接口類
public interface IBlobSergvice { Task<BlobInfo> GetBlobAsync(string name); Task<IEnumerable<string>> ListBlobsNameAsync(); Task UploadFileBlobAsync(string filePath, string filename); Task UploadContentBlobAsync(string content, string filename); Task DeleteBlobAsync(string blobName); }
BlobService 實現類
1 public class BlobService : IBlobSergvice 2 { 3 private readonly BlobServiceClient _blobServiceClient; 4 5 public BlobService(BlobServiceClient blobServiceClient) 6 { 7 this._blobServiceClient = blobServiceClient; 8 } 9 10 #region 01,獲取Blob,根據blob名稱+async Task<BlobInfo> GetBlobAsync(string name) 11 /// <summary> 12 /// 獲取Blob,根據blob名稱 13 /// </summary> 14 /// <param name="name">blob名稱</param> 15 /// <returns></returns> 16 public async Task<Azure.Storage.Models.BlobInfo> GetBlobAsync(string name) 17 { 18 var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); 19 20 var blobClient = containerClient.GetBlobClient(name); 21 var blobDownLoadInfo = await blobClient.DownloadAsync(); 22 return new Azure.Storage.Models.BlobInfo(blobDownLoadInfo.Value.Content, blobDownLoadInfo.Value.ContentType); 23 } 24 #endregion 25 26 #region 02,獲取全部Blob名稱+async Task<IEnumerable<string>> ListBlobsNameAsync() 27 /// <summary> 28 /// 獲取全部Blob名稱 29 /// </summary> 30 /// <returns></returns> 31 public async Task<IEnumerable<string>> ListBlobsNameAsync() 32 { 33 var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); 34 var items = new List<string>(); 35 36 await foreach (var blobItem in containerClient.GetBlobsAsync()) 37 { 38 items.Add(blobItem.Name); 39 } 40 return items; 41 } 42 #endregion 43 44 #region 03,上傳圖片流,根據文件路徑和文件名稱+async Task UploadFileBlobAsync(string filePath, string filename) 45 /// <summary> 46 /// 上傳圖片流,根據文件路徑和文件名稱 47 /// </summary> 48 /// <param name="filePath">文件路徑</param> 49 /// <param name="filename">文件名稱</param> 50 /// <returns></returns> 51 public async Task UploadFileBlobAsync(string filePath, string filename) 52 { 53 var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); 54 var blobClient = containerClient.GetBlobClient(filename); 55 await blobClient.UploadAsync(filePath, new BlobHttpHeaders { ContentType = filePath.GetContentType() }); 56 } 57 #endregion 58 59 #region 04,上傳文件流,根據文件內容和文件名稱+async Task UploadContentBlobAsync(string content, string filename) 60 /// <summary> 61 /// 上傳文件流,根據文件內容和文件名稱 62 /// </summary> 63 /// <param name="content">文件內容</param> 64 /// <param name="filename">文件名稱</param> 65 /// <returns></returns> 66 public async Task UploadContentBlobAsync(string content, string filename) 67 { 68 var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); 69 var blobClient = containerClient.GetBlobClient(filename); 70 var bytes = Encoding.UTF8.GetBytes(content); 71 await using var memoryStream = new MemoryStream(bytes); 72 await blobClient.UploadAsync(memoryStream, new BlobHttpHeaders() { ContentType = filename.GetContentType() }); 73 } 74 #endregion 75 76 #region 05,刪除Blob+async Task DeleteBlobAsync(string blobName) 77 /// <summary> 78 /// 刪除Blob 79 /// </summary> 80 /// <param name="blobName">blob名稱</param> 81 /// <returns></returns> 82 public async Task DeleteBlobAsync(string blobName) 83 { 84 var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); 85 var blobClient = containerClient.GetBlobClient(blobName); 86 await blobClient.DeleteIfExistsAsync(); 87 } 88 #endregion 89 }
UpLoadContentRequest
1 public class UpLoadContentRequest 2 { 3 /// <summary> 4 /// 文件內容 5 /// </summary> 6 public string Content { get; set; } 7 8 /// <summary> 9 /// 文件名稱 10 /// </summary> 11 public string FileName { get; set; } 12 }
UploadFileRequest
1 public class UploadFileRequest 2 { 3 /// <summary> 4 /// 文件路徑 5 /// </summary> 6 public string FilePath { get; set; } 7 8 /// <summary> 9 /// 文件名稱 10 /// </summary> 11 public string FileName { get; set; } 12 }
FileExtensions 擴展類
1 public static class FileExtensions 2 { 3 private static readonly FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider(); 4 5 public static string GetContentType(this string fileName) 6 { 7 if (!provider.TryGetContentType(fileName, out var contentType)) 8 { 9 contentType = "application/octet-stream"; 10 } 11 return contentType; 12 } 13 }
目前咱們分別添加了 上傳圖片接口,上傳文件接口,刪除文件接口
咱們分別在 postman 中進行測試
(1)上傳圖片
FilePath(文件路徑):」C:\\Users\\admin\\Desktop\\2020904001.jpg「
FileName(文件名稱):」2020904001.jpg「
點擊 」Send「,咱們能夠看到響應返回狀態碼(Status) 」200 OK「
同時在 Portal 上也能夠看到剛剛選擇的 」20200904001.jpg「 文件
這裏注意一下,爲何咱們制定文件的路徑,和名稱就能夠上傳文件,而且能夠在瀏覽器中查看,那是由於咱們在上傳文件中設置文件的請求頭的緣由
private static readonly FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider(); public static string GetContentType(this string fileName) { if (!provider.TryGetContentType(fileName, out var contentType)) { contentType = "application/octet-stream"; } return contentType; }
public async Task UploadFileBlobAsync(string filePath, string filename) { var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); var blobClient = containerClient.GetBlobClient(filename); await blobClient.UploadAsync(filePath, new BlobHttpHeaders { ContentType = filePath.GetContentType() }); }
(2)上傳json文件
Content:"{ \"Name\" : \"zhangsan\", \"Reamrk\" : \"This is work!!!\" }"
FileName:」log.json「
點擊 」Send「,上傳 Json 文件
咱們繼續在 Portal 上進行查看上傳的 json 文件
(3)查看 Blob 信息
接下來仍是刪除 Blob 數據的操做,我這裏就不作演示了,你們能夠本身調用接口進行測試
好的,那今天的內容就先到此結束,今天的目的只是經過簡單的demo代碼去演示若是操做 Azure Blob 數據,簡單的跑跑代碼,在.NET Core 中的demo代碼是怎麼去寫的,具體的Azure.Storage 類中的方法,參數等今天的內容暫時不去解釋。
鼓掌,撒花🎉🎉🎉🎉🎉
今天的文章大概介紹了在 Portal 上如何上傳 blob 圖片文件,以及寫了一個簡單的 .NET Core demo 程序,經過代碼咱們咱們去控制 Blob 數據的增刪改查,下一篇繼續介紹 Azure Storage 在代碼中的操做,也着重講一下Azure.Storage 中的類,以及方法的具體調用和說明。
github:https://github.com/yunqian44/Azure.Storage.git
做者:Allen
版權:轉載請在文章明顯位置註明做者及出處。如發現錯誤,歡迎批評指正。