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

Go语言实现对象存储——下载任意图片,保存到阿里云存储,并将URL保存到数据库。

提前到阿里云获取三个月免费的对象存储资源

用户登录名称 xxx.onaliyun.com
AccessKey ID 
AccessKey Secret 

go mod init your_project_name
go mod tidy
go get github.com/aliyun/aliyun-oss-go-sdk/oss
go get github.com/go-sql-driver/mysql

使用阿里云OSS SDK将图片上传到阿里云存储,并将URL保存到MySQL数据库。

项目结构

.
├── main.go
├── config
│   └── config.go
├── database
│   └── database.go
├── oss
│   └── oss.go
└── utils└── utils.go

1. 配置文件 (config/config.go)

package configconst (// 阿里云OSS配置OSSEndpoint        = "oss-cn-hangzhou.aliyuncs.com" // 根据你的实际区域修改OSSBucketName      = "your-bucket-name"             // 替换为你的bucket名称OSSAccessKeyId     = "LTAI5tLi17zqqJyZdqYLE24p"OSSAccessKeySecret = "vxvWYpfQfBErvWWNCXrP7aWxiZV9Pi"// 数据库配置DBDriver   = "mysql"DBUser     = "remote_user"DBPassword = "Sctl@123456"DBHost     = "localhost"DBPort     = "3306"DBName     = "test2"// 本地临时存储路径LocalTempDir = "./temp"
)

2. 数据库操作 (database/database.go)

package databaseimport ("database/sql""fmt""log""time"_ "github.com/go-sql-driver/mysql""your_project_name/config" // 替换为你的项目名
)var DB *sql.DBfunc InitDB() error {var err errordsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8",config.DBUser,config.DBPassword,config.DBHost,config.DBPort,config.DBName)DB, err = sql.Open(config.DBDriver, dsn)if err != nil {return fmt.Errorf("failed to open database: %v", err)}// 测试数据库连接if err = DB.Ping(); err != nil {return fmt.Errorf("failed to ping database: %v", err)}// 创建表(如果不存在)createTableSQL := `CREATE TABLE IF NOT EXISTS images (id INT AUTO_INCREMENT PRIMARY KEY,add_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,url VARCHAR(255) NOT NULL)`_, err = DB.Exec(createTableSQL)if err != nil {return fmt.Errorf("failed to create table: %v", err)}log.Println("Database initialized successfully")return nil
}func SaveImageURL(url string) error {insertSQL := `INSERT INTO images (url) VALUES (?)`_, err := DB.Exec(insertSQL, url)if err != nil {return fmt.Errorf("failed to save image URL: %v", err)}return nil
}

3. OSS操作 (oss/oss.go)

package ossimport ("fmt""io""log""time""github.com/aliyun/aliyun-oss-go-sdk/oss""your_project_name/config" // 替换为你的项目名
)var Client *oss.Client
var Bucket *oss.Bucketfunc InitOSS() error {var err error// 创建OSSClient实例Client, err = oss.New(config.OSSEndpoint, config.OSSAccessKeyId, config.OSSAccessKeySecret)if err != nil {return fmt.Errorf("failed to create OSS client: %v", err)}// 获取存储空间Bucket, err = Client.Bucket(config.OSSBucketName)if err != nil {return fmt.Errorf("failed to get bucket: %v", err)}log.Println("OSS initialized successfully")return nil
}func UploadFileToOSS(localFilePath, objectName string) (string, error) {// 上传文件err := Bucket.PutObjectFromFile(objectName, localFilePath)if err != nil {return "", fmt.Errorf("failed to upload file to OSS: %v", err)}// 获取文件URLsignedURL, err := Bucket.SignURL(objectName, oss.HTTPGet, 3600 * 24 * 365) // 1年有效期的URLif err != nil {return "", fmt.Errorf("failed to generate signed URL: %v", err)}return signedURL, nil
}func GenerateObjectName(filename string) string {// 使用时间戳+随机数生成唯一的文件名timestamp := time.Now().UnixNano()return fmt.Sprintf("images/%d_%s", timestamp, filename)
}

4. 工具函数 (utils/utils.go)

package utilsimport ("fmt""io""net/http""os""path/filepath"
)func DownloadImage(imageURL, localPath string) error {// 创建HTTP GET请求resp, err := http.Get(imageURL)if err != nil {return fmt.Errorf("failed to download image: %v", err)}defer resp.Body.Close()// 检查响应状态码if resp.StatusCode != http.StatusOK {return fmt.Errorf("bad status: %s", resp.Status)}// 创建本地文件out, err := os.Create(localPath)if err != nil {return fmt.Errorf("failed to create local file: %v", err)}defer out.Close()// 将响应体复制到文件_, err = io.Copy(out, resp.Body)if err != nil {return fmt.Errorf("failed to save image to file: %v", err)}return nil
}func EnsureDir(dirPath string) error {// 检查目录是否存在if _, err := os.Stat(dirPath); os.IsNotExist(err) {// 创建目录err = os.MkdirAll(dirPath, 0755)if err != nil {return fmt.Errorf("failed to create directory: %v", err)}}return nil
}func GetFilenameFromURL(url string) string {// 从URL中提取文件名// 简单实现,实际可能需要更复杂的处理return filepath.Base(url)
}

5. 主程序 (main.go)

package mainimport ("fmt""log""os""path/filepath""your_project_name/config"      // 替换为你的项目名"your_project_name/database"    // 替换为你的项目名"your_project_name/oss"         // 替换为你的项目名"your_project_name/utils"       // 替换为你的项目名
)func main() {// 初始化配置fmt.Println("Initializing application...")// 初始化数据库if err := database.InitDB(); err != nil {log.Fatalf("Failed to initialize database: %v", err)}defer database.DB.Close()// 初始化OSSif err := oss.InitOSS(); err != nil {log.Fatalf("Failed to initialize OSS: %v", err)}// 示例图片URL (可以替换为从命令行参数或配置中获取)imageURL := "https://example.com/sample.jpg" // 替换为实际的图片URL// 确保临时目录存在if err := utils.EnsureDir(config.LocalTempDir); err != nil {log.Fatalf("Failed to ensure temp directory: %v", err)}// 从URL获取文件名filename := utils.GetFilenameFromURL(imageURL)localFilePath := filepath.Join(config.LocalTempDir, filename)// 1. 下载图片到本地fmt.Printf("Downloading image from %s...\n", imageURL)if err := utils.DownloadImage(imageURL, localFilePath); err != nil {log.Fatalf("Failed to download image: %v", err)}fmt.Println("Image downloaded successfully")// 2. 上传图片到OSSobjectName := oss.GenerateObjectName(filename)fmt.Printf("Uploading image to OSS as %s...\n", objectName)ossURL, err := oss.UploadFileToOSS(localFilePath, objectName)if err != nil {log.Fatalf("Failed to upload image to OSS: %v", err)}fmt.Printf("Image uploaded to OSS successfully. URL: %s\n", ossURL)// 3. 保存URL到数据库fmt.Println("Saving URL to database...")if err := database.SaveImageURL(ossURL); err != nil {log.Fatalf("Failed to save URL to database: %v", err)}fmt.Println("URL saved to database successfully")// 清理临时文件if err := os.Remove(localFilePath); err != nil {log.Printf("Warning: failed to remove temporary file: %v", err)}fmt.Println("Process completed successfully")
}

6. 项目依赖

你需要安装以下依赖:

go get github.com/aliyun/aliyun-oss-go-sdk/oss
go get github.com/go-sql-driver/mysql

7. 使用说明

  1. 将上述代码按照项目结构创建好文件
  2. 替换your_project_name为你的实际项目名
  3. 修改config/config.go中的OSSBucketName为你的实际bucket名称
  4. 确保你的阿里云OSS bucket已经创建,并且有正确的权限
  5. 确保MySQL数据库已经创建,并且有正确的访问权限
  6. 运行程序:go run main.go

8. 注意事项

  1. 安全性:在实际生产环境中,不要将AccessKey直接硬编码在代码中,应该使用环境变量或配置管理工具
  2. 错误处理:代码中已经包含了基本的错误处理,但在生产环境中可能需要更详细的日志记录
  3. 并发处理:如果需要处理多个图片,可以考虑使用goroutine并发处理
  4. 文件名生成:当前实现使用时间戳+随机数生成文件名,可以根据需求调整
  5. URL有效期:当前实现生成的是1年有效期的URL,可以根据需求调整

http://www.dtcms.com/a/294250.html

相关文章:

  • 【数据库】国产数据库的新机遇:电科金仓以融合技术同步全球竞争
  • Pycaita二次开发基础代码解析:图层管理、基准控制与特征解析深度剖析
  • lwIP学习记录5——裸机lwIP工程学习后的总结
  • 【C++】类和对象(中)构造函数、析构函数
  • 海信IP501H-IP502h_GK6323处理器-原机安卓9专用-优盘卡刷固件包
  • ZLMediaKit流媒体服务器WebRTC页面显示:使用docker部署
  • Android多开实现方案深度分析
  • Android13重置锁屏(2)
  • 论文略读:Knowledge is a Region in Weight Space for Finetuned Language Models
  • springboot集成LangChain4j
  • 世博会无法在Android上启动项目:无法连接到TCP端口5554:连接被拒绝
  • 2025暑期—05神经网络-BP网络
  • PyCharm配置python软件安装步骤(附安装包)PyCharm 2025 超详细下载安装教程
  • 【CNN】LeNet网络架构
  • 盟接之桥说制造:浅谈“客供共生关系”:构建能力闭环,实现价值共赢
  • 论文笔记:On the Biology of a Large Language Model
  • Java 高频算法
  • Python通关秘籍(七)数据结构——集合
  • mysql什么时候用char,varchar,text,longtext
  • Git 完全手册:从入门到团队协作实战(4)
  • 经典神经网络之LetNet
  • 【前沿技术动态】【AI总结】RustFS:从 0 到 1 打造下一代分布式对象存储
  • Java 时间处理 API 全解析:从 JDK7 到 JDK8 的演进
  • 有序数组中出现次数超过25%的元素
  • 数字人形象视频:开启虚拟世界的全新篇章
  • Linux 723 磁盘配额 限制用户写入 quota;snap快照原理
  • IRF 真机实验
  • [AI8051U入门第八步]硬件IIC驱动AHT10温湿度传感器
  • 密码学中的概率论与统计学:从频率分析到现代密码攻击
  • 【Kubernetes】集群启动nginx,观察端口映射,work节点使用kubectl配置