当前位置: 首页 > news >正文

如何使用 Go语言操作亚马逊 S3 对象云存储

以下是使用 Go 语言操作亚马逊 S3 对象云存储的详细步骤和示例代码:

解决思路:

  1. 安装必要的 Go 语言包,这里我们将使用 aws-sdk-go 包来与 Amazon S3 进行交互。
  2. 配置 AWS 凭证,包括访问密钥和秘密访问密钥,以及 AWS 区域。
  3. 使用 aws-sdk-go 创建 S3 客户端。
  4. 通过 S3 客户端执行各种操作,如上传文件、下载文件、列出存储桶中的对象等。

示例代码:

package s3Uploaderimport ("bytes""errors""fmt""github.com/aws/aws-sdk-go/aws""github.com/aws/aws-sdk-go/aws/credentials""github.com/aws/aws-sdk-go/aws/session""github.com/aws/aws-sdk-go/service/s3/s3manager""github.com/chai2010/webp" // WebP 库"github.com/nfnt/resize""html""image""image/jpeg""image/png""net/http""os""strings""upos/src/config"
)type S3Uploader struct {Name        stringScale       config.ScaleCfg         config.Sharktechuploader    *s3manager.UploaderContentType string
}var (ErrorUnsupportedImageFormat = errors.New("不支持的图片格式")
)func NewS3Uploader(cfg config.Sharktech) (*S3Uploader, error) {sess, err := session.NewSession(&aws.Config{Region:   aws.String(cfg.S3.Region),Endpoint: aws.String(cfg.S3.Endpoint),/*Set this to `true` to force the request to use path-style addressing,i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 clientwill use virtual hosted bucket addressing when possible(`http://BUCKET.s3.amazonaws.com/KEY`).*/S3ForcePathStyle: aws.Bool(true),Credentials:      credentials.NewStaticCredentials(cfg.S3.AccessId, cfg.S3.AccessKey, ""),})if err != nil {return nil, err}uploader := s3manager.NewUploader(sess)return &S3Uploader{Cfg:      cfg,Scale:    config.YC.Scale,uploader: uploader,}, nil
}func (u *S3Uploader) ConvertWebPToJPG(file *os.File) (image.Image, error) {// 解码 WebP 文件为 image.Imageimg, err := webp.Decode(file)if err != nil {return nil, fmt.Errorf("解码 WebP 文件失败: %w", err)}return img, nil
}func (u *S3Uploader) ScaleImage(img image.Image, maxWidth, maxHeight uint) image.Image {// 获取原始图片的宽度和高度originalWidth := img.Bounds().Dx()originalHeight := img.Bounds().Dy()// 计算缩放比例ratio := float64(originalWidth) / float64(originalHeight)var newWidth, newHeight uintif ratio > 1 { // 图片宽 > 高newWidth = maxWidthnewHeight = uint(float64(maxWidth) / ratio)} else { // 图片高 >= 宽newHeight = maxHeightnewWidth = uint(float64(maxHeight) * ratio)}return resize.Resize(newWidth, newHeight, img, resize.Lanczos3)
}// 根据图片格式生成 Content-Type
func (u *S3Uploader) getContentType(format string) string {switch strings.ToLower(format) {case ".jpg", ".jpeg":return "image/jpeg"case ".png":return "image/png"case ".webp":return "image/webp"default:return "application/octet-stream" // 默认值}
}// 根据文件扩展名选择编码格式
func (u *S3Uploader) encodeImage(buf *bytes.Buffer, img image.Image, format string) error {switch strings.ToLower(format) {case ".jpg", ".jpeg":return jpeg.Encode(buf, img, nil)case ".png":return png.Encode(buf, img)case ".webp":return webp.Encode(buf, img, &webp.Options{Lossless: true})default:return ErrorUnsupportedImageFormat}
}// DetectFormatAndDecode 根据文件头判断图片格式并解码
func (u *S3Uploader) DetectFormatAndDecode(filePath string) (image.Image, string, error) {// 打开文件file, err := os.Open(filePath)if err != nil {return nil, "", err}defer file.Close()// 读取文件头前 12 个字节header := make([]byte, 12)_, err = file.Read(header)if err != nil {return nil, "", err}// 重置文件读取位置_, err = file.Seek(0, 0)if err != nil {return nil, "", err}// 根据文件头判断格式var img image.Imagevar ext stringswitch {case bytes.HasPrefix(header, []byte("\xFF\xD8\xFF")):// JPEG 文件头img, err = jpeg.Decode(file)ext = ".jpg"case bytes.HasPrefix(header, []byte("\x89PNG\r\n\x1a\n")):// PNG 文件头img, err = png.Decode(file)ext = ".png"case bytes.HasPrefix(header, []byte("RIFF")) && bytes.Contains(header[8:], []byte("WEBP")):// WebP 文件头img, err = webp.Decode(file)ext = ".webp"default:err = errors.New("unsupported image format")}return img, ext, err
}func (u *S3Uploader) Resize(filePath string) (buf bytes.Buffer, err error) {newImg, ext, err := u.DetectFormatAndDecode(filePath)if err != nil {return bytes.Buffer{}, err}u.ContentType = u.getContentType(ext)// 将缩放后的图片编码为 JPEG 格式err = u.encodeImage(&buf, newImg, ext)if err != nil {return}return buf, nil
}func (u *S3Uploader) Upload(filePath string, key string) error {buf, err := u.Resize(filePath)if err != nil {return err}_, err = u.uploader.Upload(&s3manager.UploadInput{ACL:    aws.String("public-read"), // 设置为 public-readBucket: aws.String(u.Cfg.S3.Bucket),Key:    aws.String(key),// TODO:: 不传Content-Type的好处是WP站点不好外链// ContentType: aws.String(u.ContentType),Body: bytes.NewReader(buf.Bytes()),})if err != nil {return err}return nil
}func (u *S3Uploader) DownloadAndUpload(imageUrl string, key string) error {buf, err := u.DownloadAndResizeImage(imageUrl)if err != nil {return err}_, err = u.uploader.Upload(&s3manager.UploadInput{ACL:    aws.String("public-read"), // 设置为 public-readBucket: aws.String(u.Cfg.S3.Bucket),Key:    aws.String(key),// TODO:: 不传Content-Type的好处是WP站点不好外链// ContentType: aws.String(u.ContentType),Body: bytes.NewReader(buf.Bytes()),})if err != nil {return err}return nil
}func (u *S3Uploader) DownloadAndResizeImage(imgURL string) (buf bytes.Buffer, err error) {imgURL = html.UnescapeString(imgURL)// 创建请求req, err := http.NewRequest("GET", imgURL, nil)if err != nil {return}// 设置 Referer 或 User-Agent,模拟合法请求req.Header.Set("Referer", "https://www.google.com")req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36")// 发起请求client := &http.Client{}resp, err := client.Do(req)if err != nil {return}defer resp.Body.Close()// 检查响应的Content-TypecontentType := resp.Header.Get("Content-Type")// log.Println("Content-Type:", contentType)if !strings.HasPrefix(contentType, "image/") {err = fmt.Errorf("invalid content type: %s", contentType)return}// 读取图片img, _, err := image.Decode(resp.Body)if err != nil {return}newImg := u.ScaleImage(img, u.Scale.Width, u.Scale.Height)// 将缩放后的图片编码为 JPG 格式err = u.encodeImage(&buf, newImg, ".jpg")if err != nil {return}return buf, nil
}

相关文章:

如何使用 Go语言操作亚马逊 S3 对象云存储

以下是使用 Go 语言操作亚马逊 S3 对象云存储的详细步骤和示例代码: 解决思路: 安装必要的 Go 语言包,这里我们将使用 aws-sdk-go 包来与 Amazon S3 进行交互。配置 AWS 凭证,包括访问密钥和秘密访问密钥,以及 AWS 区…...

2025年应用与API安全展望:挑战与机遇并存

进入2025年,应用与API安全的重要性愈发突出。在过去的一年里,API技术已经成为数字创新的核心。然而,API的大规模应用也使得攻击面显著扩展,2024年针对业务逻辑漏洞的API攻击占比高达27%,较前一年增加10%。与此同时&…...

Linux安装docker,安装配置xrdp远程桌面

Linux安装docker,安装配置xrdp远程桌面。 1、卸载旧版本docker 卸载旧版本docker命令 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine现在就是没有旧版本的d…...

VD:生成a2l文件

目录 前言Simulink合并地址 ASAP2 editor 前言 我之前的方法都是通过Simulink模型生成代码的过程中顺便就把a2l文件生成出来了,这时的a2l文件还没有地址,所以紧接着会去通过elf文件更新地址,一直以为这是固定的流程和方法,今天无…...

【SpringBoot应用篇】SpringBoot+MDC+自定义Filter操作traceId实现日志链路追踪

【SpringBoot应用篇】SpringBootMDC自定义Filter操作traceId实现日志链路追踪 解决的问题解决方案MDC具体逻辑ymllogback-spring.xmlTraceIdUtil操作工具类TraceIdFilter自定义过滤器GlobalExceptionHandler全局异常处理类TraceIdAspect切面UserController测试验证 多线程处理M…...

unity2022以上导出到AndroidStudio后更新步骤

1、unity里面Export出unityLibrary 2、导出apk,里面才包含libil2cpp(新版unity无法直接导出libil2cpp 3、注释AS项目app下的build.gradle里面包含unityLibrary的代码 4、注释AS项目settings.gradle包含unityLibrary的代码 5、删除AS项目里面的unityLibrary文件夹 6、…...

【ArcGIS初学】产生随机点计算混淆矩阵

混淆矩阵:用于比较分类结果和地表真实信息 总体精度(overall accuracy) :指对角线上所有样本的像元数(正确分类的像元数)除以所有像元数。 生产者精度(producers accuracy) :某类中正确分类的像元数除以参考数据中该类的像元数(列方向),又称…...

Harmony面试模版

1. 自我介绍 看表达能力、沟通能力 面试记录: 2. 进一步挖掘 2.1. 现状 目前是在职还是离职,如果离职,从上一家公司离职的原因 2.2. 项目经验 如果自我介绍工作项目经验讲的不够清楚,可以根据简历上的信息再进一步了解 面试记…...

PCM5142集成32位384kHz PCM音频立体声114dB差分输出DAC编解码芯片

目录 PCM5142 简介PCM5142功能框图PCM5142特性 参考原理图 PCM5142 简介 PCM514x 属于单片 CMOS 集成电路系列,由立体声数模转换器 (DAC) 和采用薄型小外形尺寸 (TSSOP) 封装的附加支持电路组成。PCM514x 使用 TI 最新一代高级分段 DAC 架构产品,可实现…...

浪潮云财务系统xtdysrv.asmx存在命令执行漏洞

一、漏洞简介 浪潮云财务系统xtdysrv.asmx存在命令执行漏洞,未经身份验证的远程攻击者可通过该漏洞在服务器端任意执行代码。 二、漏洞影响 浪潮云财务系统三、网络测绘: fofa: title"TSCEV4.0"四、复现过程 前置条件 步骤 POC 1 数据包…...

【网络编程】基础知识

目录 网络发展史 局域网和广域网 局域网(LAN) 广域网(Wan) 光猫 路由器 网线 设备通信的要素 IP地址 基本概念 地址划分 特殊地址(后续编程使用) IP地址转换 字节序 网络模型 网络的体系结…...

ResNet (Residual Network) - 残差网络:深度卷积神经网络的突破

一、引言 在计算机视觉领域,图像识别一直是一个核心且具有挑战性的任务。随着深度学习的发展,卷积神经网络(CNN)在图像识别方面取得了显著的成果。然而,随着网络深度的增加,出现了梯度消失或梯度爆炸等问题…...

MOSFET体二极管的反向恢复分析

1、MOSFET体二极管的反向恢复分析 MOSFET体二极管反向恢复会导致MOSFET工作时超出安全工作区(SOA),并引发其他电磁干扰问题(EMI。 二极管在反向恢复过程中会产生比较大的损耗。在正向偏置状态下,大量的电子和空穴载流…...

80_Redis内存策略

Redis性能之所以这么强,最主要的原因就是基于内存存储。而单节点的Redis其内存大小不宜过大,否则会影响持久化或主从同步的性能。 我们可以通过修改redis.conf配置文件来设置Redis的最大内存。 maxmemory <bytes> 当Redis内存使用达到上限时,就无法存储更多数据了。…...

【HarmonyOS NAPI 深度探索6】使用 N-API 创建第一个 Hello World 原生模块

【HarmonyOS NAPI 深度探索6】使用 N-API 创建第一个 Hello World 原生模块 开发一个 N-API 模块听起来可能有点技术感十足&#xff0c;但实际上入门并不复杂。今天&#xff0c;我们就来一步步实现一个简单的 Hello World 原生模块&#xff0c;感受一下 N-API 开发的魅力。 环…...

Java语言的软件工程

Java语言的软件工程 引言 在当今信息技术飞速发展的时代&#xff0c;软件工程作为一门应用广泛的学科&#xff0c;承担着开发高质量软件系统的重要责任。Java语言以其跨平台特性、安全性和强大的库支持&#xff0c;已经成为软件工程领域中最流行的编程语言之一。本文将深入探…...

【Mysql进阶知识】Mysql 程序的介绍、选项在命令行配置文件的使用、选项在配置文件中的语法

目录 一、程序介绍 二、mysqld--mysql服务器介绍 三、mysql - MySQL 命令行客户端 3.1 客户端介绍 3.2 mysql 客户端选项 指定选项的方式 mysql 客户端命令常用选项 在命令行中使用选项 选项(配置)文件 使用方法 选项文件位置及加载顺序 选项文件语法 使用举例&am…...

wireshark抓路由器上的包 抓包路由器数据

文字目录 抓包流程概述设置抓包配置选项 设置信道设置无线数据包加密信息设置MAC地址过滤器 抓取联网过程 抓包流程概述 使用Omnipeek软件分析网络数据包的流程大概可以分为以下几个步骤&#xff1a; 扫描路由器信息&#xff0c;确定抓包信道&#xff1b;设置连接路由器的…...

玩转大语言模型——使用graphRAG+Ollama构建知识图谱

系列文章目录 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 文章目录 系列文章目录前言下载和安装用下载项目的方式下载并安装用pip方式下载并安装 生成知识图谱初始化文件夹修改模型配置修改知识库生成配置创…...

python flask简单实践

项目结构 project/ │ ├── app.py ├── instance/ │ └── database.db ├── templates/ │ └── index.html ├── static/ │ └── style.css │ └── favicon.ico └── database.db首先创建目录&#xff0c;static 存放一些页面的样式或图标文件…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...