Azure Storage 系列(二) .NET Core Web 项目中操作 Blob 存储
一,引言
上一篇文章,我们介绍到在实际项目中系统会产生大量的日志文件,用户上传的头像等等,同时也介绍到可以使用Azure Blob Storage 来存储项目中的一些日志文件,用户头像,用户视频等等。这个时候,有人就会问到,那我大概明白Blob可以存放什么类型的数据了,这个时候就有人问一些问题了
1,什么是Blob?
答 Azure Blob 存储是非结构化的,它可以保存的数据类型是没有任何限制的。如,pdf文档,json文件,视频,txt文件等。我们常见的类型的文件,它统统可以进行存储。但是 Blob 不适合需要经常查询的结构化数据, 比如说项目中使用的,它们具有比内存和本地磁盘更高的延迟,并且没有可让数据库高效运行查询的索引功能。但是,blob经常用与数据库一起用于存储不可查询的的数据,例如用户头像存储在Blob中,数据库中保存对应用户头像的Blob名称或URL(来自微软官方解释)
其实用可以这么说,如果项目中有对于的图片资源,视频资源,文件等资源,我们就可以考虑到将这些数据都存储在Azure Blob中。今天在文章的后半段我们将通过一个简单的 .NET Core Web 程序去操作 Blob 存储对象。
二,正文
开始之前我们看看 Blob 的类型
1,block blob(块 blob):由不同大小的块构成,在写入到块 blob 时,需要将数据上传到块并将其提交到 blob。
2,append blob(追加 blob):是专用的块 blob,它仅支持追加新数据,追加操作非常高效。 追加 blob 非常适用于存储日志或写入流数据等方案。
3,page blob(页 blob):专用于涉及随机存取读写的方案。 页 blob 用于存储 Azure 虚拟机所使用的虚拟硬盘 (VHD) 文件,但它们非常适用于任何涉及到随机存取的方案。
今天我们演示的是 block blob类似,实际项目中,我们是如何进行操作的
1,Azure Portal 上进行创建 blob 数据
找到之前创建好的 “cnbateblogaccount” Storage Account,点击图中圈起来的 “Containers”,进行创建容器
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); }IBlobSergvice BlobService 实现类
public class BlobService : IBlobSergvice { private readonly BlobServiceClient _blobServiceClient; public BlobService(BlobServiceClient blobServiceClient) { this._blobServiceClient = blobServiceClient; } #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> G ad8 etBlobAsync(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 #region 02,获取所有Blob名称+async Task<IEnumerable<string>> ListBlobsNameAsync() /// <summary> /// 获取所有Blob名称 /// </summary> /// <returns></returns> public async Task<IEnumerable<string>> ListBlobsNameAsync() { var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); var items = new List<string>(); await foreach (var blobItem in containerClient.GetBlobsAsync()) { items.Add(blobItem.Name); } return items; } #endregion #region 03,上传图片流,根据文件路径和文件名称+async Task UploadFileBlobAsync(string filePath, string filename) /// <summary> /// 上传图片流,根据文件路径和文件名称 /// </summary> /// <param name="filePath">文件路径</param> /// <param name="filename">文件名称</param> /// <returns></returns> 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() }); } #endregion #region 04,上传文件流,根据文件内容和文件名称+async Task UploadContentBlobAsync(string content, string filename) /// <summary> /// 上传文件流,根据文件内容和文件名称 /// </summary> /// <param name="content">文件内容</param> /// <param name="filename">文件名称</param> /// <returns></returns> public async Task UploadContentBlobAsync(string content, string filename) { var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); var blobClient = containerClient.GetBlobClient(filename); var bytes = Encoding.UTF8.GetBytes(content); await using var memoryStream = new MemoryStream(bytes); await blobClient.UploadAsync(memoryStream, new BlobHttpHeaders() { ContentType = filename.GetContentType() }); } #endregion #region 05,删除Blob+async Task DeleteBlobAsync(string blobName) /// <summary> /// 删除Blob /// </summary> /// <param name="blobName">blob名称</param> /// <returns></returns> 82 public async Task DeleteBlobAsync(string blobName) { var containerClient = _blobServiceClient.GetBlobContainerClient("picturecontainer"); var blobClient = containerClient.GetBlobClient(blobName); await blobClient.DeleteIfExistsAsync(); } #endregion }BlobService
UpLoadContentRequest
public class UpLoadContentRequest { /// <summary> /// 文件内容 /// </summary> public string Content { get; set; } /// <summary> /// 文件名称 /// </summary> public string FileName { get; set; } }UpLoadContentRequest
UploadFileRequest
public class UploadFileRequest { /// <summary> /// 文件路径 /// </summary> public string FilePath { get; set; } /// <summary> /// 文件名 56c 称 /// </summary> public string FileName { get; set; } }UploadFileRequest
FileExtensions 扩展类
public static class FileExtensions 2 { 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; } }FileExtensions
目前我们分别添加了 上传图片接口,上传文件接口,删除文件接口
我们分别在 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
版权:转载请在文章明显位置注明作者及出处。如发现错误,欢迎批评指正。
- 工作和人工智能的未来
- JNPF快速开发框架的八大功能介绍
- 华为畅享20plus和荣耀x10max的区别哪个好
- 华为畅享20 Plus和华为畅享20pro 的区别 哪个好
- 华为畅享20plus和荣耀x10区别的区别 哪个好
- 自动生成纯文本表格的工具
- 5G的想象空间靠谁打造?
- 股价一夜暴涨40.8%,市值超波音、星巴克,但愿Zoom不会成为下一个TikTok | 海外头条
- 2020,中国手机大变天
- 「中科星睿」开拓遥感卫星新应用场景,以高科技赋能金融服务行业
- 华为畅享20和华为畅享20 Plus的区别
- kubernetes调整Node节点快速驱逐pod的时间
- 【Gin-API系列】实现动态路由分组(七)
- i7-1068NG7和i5-1038NG7 哪个好
- 安全邮箱如何申请,好用的邮箱申请方法
- i5-1038NG7 怎么样?相当于什么水平
- i7-1068NG7 怎么样?相当于什么水平
- 企业微信API:成员个性化新客户欢迎语的nodejs实现
- i5-1030NG7怎么样?相当于什么水平
- Ubuntu 20.04安装Anaconda3及简单使用