Simple WPF: WPF实现一个MINIO等S3兼容对象存储上传文件的小工具

news/2024/11/18 5:57:08/文章来源:https://www.cnblogs.com/mrchip/p/18293111

最新内容优先发布于个人博客:小虎技术分享站,随后逐步搬运到博客园。
创作不易,如果觉得有用请在Github上为博主点亮一颗小星星吧!

目的

之前在阿里云ECS 99元/年的活动实例上搭建了一个测试用的MINIO服务,以前都是直接当基础设施来使用的,这次准备自己学一下S3兼容API相关的对象存储开发,因此有了这个小工具。目前仅包含上传功能,后续计划开发一个类似图床的对象存储应用。

完整代码托管于Github:mrchipset/simple-wpf

包含的小知识点

  1. 通过AWSSDK使用S3 API
  2. 通过App.config对服务器的Endpoint和AccessKey进行设置
  3. 使用异步的方法响应按钮事件

cmrQLEN2KEddprIRAYxMvUX7FZCQQvCs6B8WpQ2RHNc.png

小工具的界面可以实现简单地选择文件上传到桶存储中。

实现过程

  1. 创建一个WPF项目,并完成如上图的布局
  2. 在项目中添加用户配置文件 App.config来保存服务调用的地址和访问密钥等信息
<?xml version="1.0" encoding="utf-8" ?>
<configuration><appSettings><add key="endpoint" value="YOUR_S3_ENDPOINT_URL"/><add key="accessKey" value="YOUR_ACCESS_KEY"/><add key="secretKey" value="YOUR_SECRET_KEY"/></appSettings>
</configuration>

编写一个方法,在程序启动的时候导入连接参数配置

private void loadConfiguration()
{NameValueCollection appConfig = ConfigurationManager.AppSettings;if (string.IsNullOrEmpty(appConfig["endpoint"])){ConfigurationManager.AppSettings.Set("endpoint", "endpoint");MessageBox.Show(this, "Endpoint is not set in the App.Config", "Error", MessageBoxButton.OK, MessageBoxImage.Error);this.Close();return;}if (string.IsNullOrEmpty(appConfig["accessKey"])){MessageBox.Show(this, "AccessKey is not set in the App.Config", "Error", MessageBoxButton.OK, MessageBoxImage.Error);this.Close();return;}if (string.IsNullOrEmpty(appConfig["secretKey"])){MessageBox.Show(this, "SecretKey is not set in the App.Config", "Error", MessageBoxButton.OK, MessageBoxImage.Error);this.Close();return;}_endpoint = appConfig["endpoint"];_accessKey = appConfig["accessKey"];_secretKey = appConfig["secretKey"];
}
  1. 为按钮添加响应处理函数
    由于上传需要一定的时间来完成,因此我们用async 关键字修饰上传按钮的点击事件处理函数,这样即时在上传过程中UI界面的操作也不会卡顿。函数原型如下,如果对C#的异步操作不是很熟悉的同学可以参考这篇博文:C# 使用基本的async/await实现异步
private async void uploadBtn_Click(object sender, RoutedEventArgs e)
{StringBuilder sb = new StringBuilder();sb.AppendLine($"Bucket: {Bucket}");sb.AppendLine($"File: {UploadFile}");statusTxtBlk.Text = sb.ToString();var ret = await UploadFileAsync();if (ret){statusTxtBlk.Text = "Upload Successfully!";}
}
  1. 编写上传函数
    现在到了本文最关键的一步,编写S3 Object上传接口。其实S3的接口都替我们封装好了,只需要按照官方demo的流程进行调用即可。
    先创建凭据对象和配置对象,然后创建客户端对象和上传请求,即可用客户端对象的上传方法进行上传。服务函数的完整代码如下:
 private async Task<bool> UploadFileAsync(){var credentials = new BasicAWSCredentials(_accessKey, _secretKey);var clientConfig = new AmazonS3Config{ForcePathStyle = true,ServiceURL = _endpoint,};bool ret = true;using (var client = new AmazonS3Client(credentials, clientConfig)) {try{var putRequest = new PutObjectRequest{BucketName = _bucket,FilePath = UploadFile};var response = await client.PutObjectAsync(putRequest);}catch(FileNotFoundException e){ret = false;this.Dispatcher.Invoke(new Action(() => this.statusTxtBlk.Text = e.Message));}catch (AmazonS3Exception e){ret = false;if (e.ErrorCode != null &&(e.ErrorCode.Equals("InvalidAccessKeyId") ||e.ErrorCode.Equals("InvalidSecurity"))){this.Dispatcher.Invoke(new Action(() => this.statusTxtBlk.Text = "Please check the provided AWS Credentials"));} else{this.Dispatcher.Invoke(new Action(() => this.statusTxtBlk.Text = $"An error occurred with the message '{e.Message}' when writing an object"));}}   }return ret;}

注意
MINIO 在使用S3函数时必须要在AmazonS3Config 中设置ForcePathStyleTrue

最终实现的效果

lO2tSD8ec3B25NI95FWqDaeHcBm33fDjvvyklqXAbL0.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/741506.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前缀和简析

前缀和 前置知识:$\sum_{i = 1}^{r}{a_i} = a_l + a_{l + 1} + \dots + a_{r - 1} + a_r$ 考虑以下数组:$i$ $1$ $2$ $3$$a_I$ $3$ $5$ $7$如果我们要查询 $\sum_{i = 1}^{2}{a_i}$,很显然可以得到 $\sum_{i = 1}^{2}{a_i} = 3 + 5 = 8$。如果我们要查询 $\sum_{i = l}^{r}{…

推挽输出和开漏输出

一、推挽输出 1.1推挽输出的概念 推挽(push-pull)输出是由两个MOS或者三极管组成,两个管子始终保持一个导通,另一个截止的状态。当输入高电平时,叫做推;上管Q1导通,下管Q2关闭;电流走向VCC→Q1→Vout。当输入低电平时,叫做挽;上管Q1关闭,下管Q2导通;电流走向Vout→…

数据血缘系列(3)—— 数据血缘可视化之美

大家好,我是独孤风。在当今数据驱动的商业环境中,数据治理成为企业成功的关键因素之一,而数据血缘正是数据治理成功的一个关键。 本文我们详细探讨下数据血缘可视化是什么,该如何实现。并顺便对比一下Apache Atlas 、Datahub、Openmetadata、Marquez、SQLLineage、Amundsen…

进度报告3

(1)1.学习Scanner来用键盘输入数据并写出实例代码并运行成功2.分支与循环结构,与c语言差不多3.Random来生成随机数用Random的案例:猜数字游戏4.数组(2)继续往后学习

防火防盗防CDN流量盗刷

没想到自己的小破站也逃不掉被攻击的命,分分钟就给我刷欠费了。本来不想写这篇文章的,但看到好多大佬(小林coding、 JavaGuide)近期cdn都被盗刷了。 还是来提醒下大家,防火防盗防cdn流量盗刷 事故时间:2024年7月5日晚8点左右 事故现场:好不容易到了周五,想着第二天就周…

记内存条硬件损坏蓝屏的 dump 文件分析

本文记录我的电脑的内存条的硬件损坏了,导致用着用着就蓝屏,我通过启动和故障恢复配置自动蓝屏打 dump 的功能,在蓝屏时创建了 dump 文件。通过分析 dump 文件大概猜测是内存的问题以下是我用 windbg 分析的两次蓝屏 第一次是用着 VS 的过程蓝屏了,我发现好多次都是使用 VS…

.NET 9 预览版 5 发布

微软在6月发布了.NET 9预览版的第五个版本。这个新版本的框架预计将在今年晚些时候正式发布,它是一个标准支持(STS)版本,将在2024年11月12日至2026年5月12日期间在多个操作系统上获得18个月的支持。这个预览版带来了性能改进和一些新特性,例如增强的AI能力、优先级无界通道…

EasyExcel当导出的文件内容为空时,报错excel无法打开xxxx,因为文件格式或扩展名无效,请确定文件未损坏

问题 EasyExcel 导出打开提示"Excel 无法打开文件 xxxxx.xlsx ,因为文件格式或文件扩展名无效 请确定文件未损坏,并且文件扩展名与文件的格式匹 排查 发现是在mysql查询完要导出的数据后,判断查询内容是否有值,如果有的话才进行excelWriter.write(dataList, writeSheet)…

读人工智能全传08人工智能的今天

读人工智能全传08人工智能的今天1. 人工智能的今天 1.1. 未来,或许有些领域会有非常明显的人工智能痕迹,有些领域则不会 1.2. 2018年,来自计算机视觉处理器公司英伟达的研究人员证明了人工智能软件能够创造出虚假的人物照片,并且能够完全令人相信它是…

Java CompletableFuture因在上下文中使用共享变量,导致线程安全问题

背景 在使用CompletableFuture.supplyAsync()时,多个异步中,同时共用的一个查询对象参数,而且在这多个任务中间会穿插地对这个对象进行更改,出现的现象就是可能会导致最终get()结果不符合我们的预期。最终调整方案就是在每个任务supplyAsync()之前单独赋予一个新的final对象…

MySQL中修改一个数据库下包含有某个相同字段的所有表的字段长度

背景 由于业务场景导致某个字段如phone_name涉及到表比较多,目前很多表都有冗余这个字段,但是前期给的字段长度只有varchar(100),不满足目前的需要了,需要把所有的表的字段长度都增大到varchar(255),如果手动一个个修改的话,那么有几百张表,很花时间,所有想到如下办法,…

领取serv00免费虚拟主机

参考 ‍ 教程地址【免费serv00虚拟机SSH登录搭建网站】 ‍ 领取地址 ​​ 领到了 ​​ 登录成功 ​​ 放放上自己的静态网站 ​​ ‍ soulio.serv00.net 缺点:网站的URL中含有中文就会404。权限很少,改不了服务器配置。如果是nginx就好了,nginx支持中文路径。 ​​ URL全英文…