AWS S3 协议对接 minio/oss 等
使用亚马逊 S3 协议访问对象存储 [s3-API](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/API/API_Operations_Amazon_Simple_Storage_Service.html)- 兼容S3协议的对象存储有- minio- 似乎是完全兼容 [兼容文档](https://www.minio.org.cn/product/s3-compatibility.html)- 阿里云oss- [兼容主要的 API ](https://help.aliyun.com/zh/oss/developer-reference/compatibility-with-amazon-s3?spm=a2c4g.11186623.0.0.590b32bcHb4D6a)- 七牛云oss- 等等
依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--使用的依赖--><dependency><groupId>com.amazonaws</groupId><artifactId>aws-java-sdk-s3</artifactId><version>1.12.522</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency></dependencies>
读取配置
package com.xx.awss3demo.config;import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data
@ConfigurationProperties(prefix = "s3")
@Component
public class S3Properties {/*** 对象存储服务的URL*/private String endpoint;/*** path-style nginx 反向代理和S3默认支持* 模式 {http://bucketname.endpoint} -- true* 模式 {http://endpoint/bucketname} -- false*/private Boolean pathStyleAccess = false;/*** 区域*/private String region;/*** Access key就像用户ID,可以唯一标识你的账户*/private String accessKey;/*** Secret key是你账户的密码*/private String secretKey;/*** 最大线程数,默认: 100*/private Integer maxConnections = 50;}
配置文件
server:port: 8888s3:# aliyun oss#endpoint: http://oss-cn-shanghai.aliyuncs.com#accessKey: #secretKey: # minioendpoint: http://192.168.1.1:9000accessKey: adminsecretKey: admin1234bucketName: lqs3bucketregion:maxConnections: 100
文件操作
package com.xx.awss3demo.service;import com.amazonaws.ClientConfiguration;
import com.amazonaws.ClientConfigurationFactory;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.util.IOUtils;
import com.liuqi.awss3demo.config.S3Properties;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.PostConstruct;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;@ConditionalOnClass(S3Properties.class)
@Service
@Log4j2
public class S3FileService {@Autowiredprivate S3Properties s3Properties;private AmazonS3 amazonS3;@PostConstructpublic void init() {log.info(s3Properties);amazonS3 = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(s3Properties.getAccessKey(), s3Properties.getSecretKey()))).withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(s3Properties.getEndpoint(),s3Properties.getRegion())).withPathStyleAccessEnabled(s3Properties.getPathStyleAccess()).withChunkedEncodingDisabled(true).withClientConfiguration(new ClientConfiguration().withMaxConnections(s3Properties.getMaxConnections()).withMaxErrorRetry(1)).build();}/*** 创建bucket* 注意:bucket name 不允许有特殊字符及大写字母** @param bucketName bucket名称* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucket">AWS API* Documentation</a>*/@SneakyThrowspublic void createBucket(String bucketName) {if (!bucketName.toLowerCase().equals(bucketName)) {throw new RuntimeException("bucket name not allow upper case");}if (checkBucketExist(bucketName)) {log.info("bucket: {} 已经存在", bucketName);return;}amazonS3.createBucket((bucketName));}@SneakyThrowspublic boolean checkBucketExist(String bucketName) {return amazonS3.doesBucketExistV2(bucketName);}/*** 获取全部bucket* <p>** @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBuckets">AWS* API Documentation</a>*/@SneakyThrowspublic List<Bucket> getAllBuckets() {return amazonS3.listBuckets();}/*** 根据bucket获取bucket详情** @param bucketName bucket名称* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBuckets">AWS* API Documentation</a>*/@SneakyThrowspublic Optional<Bucket> getBucket(String bucketName) {return amazonS3.listBuckets().stream().filter(b -> b.getName().equals(bucketName)).findFirst();}/*** @param bucketName bucket名称* @see <a href=* "http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucket">AWS API* Documentation</a>*/@SneakyThrowspublic void removeBucket(String bucketName) {amazonS3.deleteBucket(bucketName);}/*** 复制文件* @param bucketName* @param srcObjectName* @param tarObjectName*/public void copyObject(String bucketName, String srcObjectName,String tarObjectName){amazonS3.copyObject(bucketName,srcObjectName,bucketName,tarObjectName);}/*** 上传文件,指定文件类型** @param bucketName bucket名称* @param objectName 文件名称* @param stream 文件流* @param contextType 文件类型* @throws Exception*/@SneakyThrowspublic void putObject(String bucketName, String objectName, InputStream stream,String contextType) {ObjectMetadata objectMetadata = new ObjectMetadata();objectMetadata.setContentLength(stream.available());objectMetadata.setContentType(contextType);putObject(bucketName, objectName, stream, objectMetadata);}/*** 上传文件** @param bucketName bucket名称* @param objectName 文件名称* @param stream 文件流* @throws Exception*/@SneakyThrowspublic void putObject(String bucketName, String objectName, InputStream stream) {ObjectMetadata objectMetadata = new ObjectMetadata();objectMetadata.setContentLength(stream.available());objectMetadata.setContentType("application/octet-stream");putObject(bucketName, objectName, stream, objectMetadata);}/*** 上传文件** @param bucketName bucket名称* @param objectName 文件名称* @param stream 文件流* @param objectMetadata 对象元数据* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObject">AWS* API Documentation</a>*/@SneakyThrowsprivate PutObjectResult putObject(String bucketName, String objectName, InputStream stream,ObjectMetadata objectMetadata) {byte[] bytes = IOUtils.toByteArray(stream);ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);// 上传return amazonS3.putObject(bucketName, objectName, byteArrayInputStream, objectMetadata);}/*** 判断object是否存在** @param bucketName bucket名称* @param objectName 文件名称* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObject">AWS* API Documentation</a>*/@SneakyThrowspublic boolean checkObjectExist(String bucketName, String objectName) {return amazonS3.doesObjectExist(bucketName, objectName);}/*** 获取文件** @param bucketName bucket名称* @param objectName 文件名称* @return 二进制流* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObject">AWS* API Documentation</a>*/@SneakyThrowspublic S3Object getObject(String bucketName, String objectName) {return amazonS3.getObject(bucketName, objectName);}/*** 删除文件** @param bucketName bucket名称* @param objectName 文件名称* @throws Exception* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObject">AWS* API Documentation</a>*/@SneakyThrowspublic void deleteObject(String bucketName, String objectName) {amazonS3.deleteObject(bucketName, objectName);}/*** 大文件分段上传** @param file MultipartFile* @param bucketName bucketName* @param objectName objectName* @param minPartSize 每片大小,单位:字节(eg:5242880 <- 5m)*/public void uploadMultipartFileByPart(MultipartFile file, String bucketName, String objectName,int minPartSize) {if (file.isEmpty()) {log.error("file is empty");}// 计算分片大小long size = file.getSize();// 得到总共的段数,和 分段后,每个段的开始上传的字节位置List<Long> positions = Collections.synchronizedList(new ArrayList<>());long filePosition = 0;while (filePosition < size) {positions.add(filePosition);filePosition += Math.min(minPartSize, (size - filePosition));}if (log.isDebugEnabled()) {log.debug("总大小:{},分为{}段", size, positions.size());}// 创建一个列表保存所有分传的 PartETag, 在分段完成后会用到List<PartETag> partETags = Collections.synchronizedList(new ArrayList<>());// 第一步,初始化,声明下面将有一个 Multipart Upload// 设置文件类型ObjectMetadata metadata = new ObjectMetadata();metadata.setContentType(file.getContentType());InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(bucketName,objectName, metadata);InitiateMultipartUploadResult initResponse = this.initiateMultipartUpload(initRequest);if (log.isDebugEnabled()) {log.debug("开始上传");}//声明线程池ExecutorService exec = Executors.newFixedThreadPool(3);long begin = System.currentTimeMillis();try {// MultipartFile 转 FileFile toFile = multipartFileToFile(file);for (int i = 0; i < positions.size(); i++) {int finalI = i;exec.execute(() -> {long time1 = System.currentTimeMillis();UploadPartRequest uploadRequest = new UploadPartRequest().withBucketName(bucketName).withKey(objectName).withUploadId(initResponse.getUploadId()).withPartNumber(finalI + 1).withFileOffset(positions.get(finalI)).withFile(toFile).withPartSize(Math.min(minPartSize, (size - positions.get(finalI))));// 第二步,上传分段,并把当前段的 PartETag 放到列表中partETags.add(this.uploadPart(uploadRequest).getPartETag());if (log.isDebugEnabled()) {log.debug("第{}段上传耗时:{}", finalI + 1, (System.currentTimeMillis() - time1));}});}//任务结束关闭线程池exec.shutdown();//判断线程池是否结束,不加会直接结束方法while (true) {if (exec.isTerminated()) {break;}}// 第三步,完成上传,合并分段CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(bucketName,objectName,initResponse.getUploadId(), partETags);this.completeMultipartUpload(compRequest);//删除本地缓存文件if (toFile != null && !toFile.delete()) {log.error("Failed to delete cache file");}} catch (Exception e) {this.abortMultipartUpload(new AbortMultipartUploadRequest(bucketName, objectName,initResponse.getUploadId()));log.error("Failed to upload, " + e.getMessage());}if (log.isDebugEnabled()) {log.debug("总上传耗时:{}", (System.currentTimeMillis() - begin));}}/*** 根据文件前置查询文件集合** @param bucketName bucket名称* @param prefix 前缀* @param recursive 是否递归查询* @return S3ObjectSummary 列表* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjects">AWS* API Documentation</a>*/@SneakyThrowspublic List<S3ObjectSummary> getAllObjectsByPrefix(String bucketName, String prefix,boolean recursive) {ObjectListing objectListing = amazonS3.listObjects(bucketName, prefix);return new ArrayList<>(objectListing.getObjectSummaries());}/*** 查询文件版本** @param bucketName bucket名称* @return S3ObjectSummary 列表* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjects">AWS* API Documentation</a>*/@SneakyThrowspublic List<S3VersionSummary> getAllObjectsVersionsByPrefixV2(String bucketName,String objectName) {VersionListing versionListing = amazonS3.listVersions(bucketName, objectName);return new ArrayList<>(versionListing.getVersionSummaries());}/*** 获取文件外链** @param bucketName bucket名称* @param objectName 文件名称* @param expires 过期时间 <=7 单位天* @return url*/@SneakyThrowspublic String generatePresignedUrl(String bucketName, String objectName, Integer expires) {Date date = new Date();Calendar calendar = new GregorianCalendar();calendar.setTime(date);calendar.add(Calendar.DAY_OF_MONTH, expires);URL url = amazonS3.generatePresignedUrl(bucketName, objectName, calendar.getTime());return url.toString();}/*** 开放链接,默认public没有设置访问权限* url 规则:${endPoint}/${bucketName}/${objectName}** @param bucketName* @param objectName* @return*/public String generatePublicUrl(String bucketName, String objectName) {return s3Properties.getEndpoint() + "/" + bucketName + "/" + objectName;}/*** 初始化,声明有一个Multipart Upload** @param initRequest 初始化请求* @return 初始化返回*/private InitiateMultipartUploadResult initiateMultipartUpload(InitiateMultipartUploadRequest initRequest) {return amazonS3.initiateMultipartUpload(initRequest);}/*** 上传分段** @param uploadRequest 上传请求* @return 上传分段返回* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPart">AWS* API Documentation</a>*/private UploadPartResult uploadPart(UploadPartRequest uploadRequest) {return amazonS3.uploadPart(uploadRequest);}/*** 分段合并** @param compRequest 合并请求* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUpload">AWS* API Documentation</a>*/private CompleteMultipartUploadResult completeMultipartUpload(CompleteMultipartUploadRequest compRequest) {return amazonS3.completeMultipartUpload(compRequest);}/*** 中止分片上传** @param uploadRequest 中止文件上传请求* @see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUpload">AWS* API Documentation</a>*/private void abortMultipartUpload(AbortMultipartUploadRequest uploadRequest) {amazonS3.abortMultipartUpload(uploadRequest);}/*** MultipartFile 转 File*/private File multipartFileToFile(MultipartFile file) throws Exception {File toFile = null;if (file.equals("") || file.getSize() <= 0) {file = null;} else {InputStream ins = null;ins = file.getInputStream();toFile = new File(file.getOriginalFilename());//获取流文件OutputStream os = new FileOutputStream(toFile);int bytesRead = 0;byte[] buffer = new byte[8192];while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {os.write(buffer, 0, bytesRead);}os.close();ins.close();}return toFile;}
}
测试方法
package com.xx.awss3demo;import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.liuqi.awss3demo.service.S3FileService;
import lombok.extern.log4j.Log4j2;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;@SpringBootTest
@Log4j2
class AwsS3DemoApplicationTests {@Autowiredprivate S3FileService s3FileService;public String bk="lqs3bucket";@Testvoid contextLoads() {}@Testpublic void bucketTest() {s3FileService.createBucket(bk);s3FileService.getAllBuckets().forEach(b -> System.out.println(b.getName()));s3FileService.removeBucket(bk);}@Testpublic void objectTest() throws IOException {s3FileService.createBucket(bk);if (s3FileService.checkObjectExist(bk, "d1/ss/1.txt")) {log.info("文件已经存在");}s3FileService.putObject(bk,"d1/ss/1.txt",new ByteArrayInputStream("hello world xxx".getBytes(StandardCharsets.UTF_8)));s3FileService.copyObject(bk,"d1/ss/1.txt","d1/ss/1_copy.txt");S3Object object = s3FileService.getObject(bk, "d1/ss/1_copy.txt");byte[] bytes = object.getObjectContent().readAllBytes();log.info("内容是:{}",new String(bytes,StandardCharsets.UTF_8));//s3FileService.deleteObject(bk,"1.txt");}@Testpublic void listTest(){List<S3ObjectSummary> objectList = s3FileService.getAllObjectsByPrefix(bk, "/d1", true);objectList.forEach(object->{log.info(object.getKey());});}@Testpublic void genUrlTest(){String s = s3FileService.generatePresignedUrl(bk, "1.txt", 7);System.out.println(s);}}
相关文章:
AWS S3 协议对接 minio/oss 等
使用亚马逊 S3 协议访问对象存储 [s3-API](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/API/API_Operations_Amazon_Simple_Storage_Service.html)- 兼容S3协议的对象存储有- minio- 似乎是完全兼容 [兼容文档](https://www.minio.org.cn/product/s3-compatibility.htm…...

手机便签内容不见了怎么恢复正常?
在日常生活和工作中,很多人都需要随手记录事情,例如家庭琐事、孩子相关的事情、指定时间需要完成的工作任务、会议安排等。当我们需要随时随地记录事情的时候,手机便签应用就是非常不多的选择,我们直接打开手机上的便签APP就可以新…...

【架构】Java 系统架构演进的思考
文章目录 1 前言2 单体应用架构3 垂直应用架构4 分布式架构5 SOA 架构6 微服务云架构7 总结 1 前言 随着移动互联的发展,网站、H5、移动端的应用规模也不断扩大,不管是应用的数量还是质量都得到了指数级的提升。开发者的数量与日俱增,应用的…...
Python爬虫——解析_jsonpath
jsonpath的安装 pip install jsonpathjsonpath的使用: obj json.load(open(json文件, r, encodingutf-8)) ret jsonpath.jsonpath(obj, jsonpath语法)json文件: { "store": {"book": [{ "category": "末世"…...

华为发布数字资产继承功能
在华为开发者大会2023(HDC.Together)上,华为常务董事、终端BG CEO、智能汽车解决方案BU CEO余承东正式发布了数字资产继承功能,HarmonyOS提供了安全便捷的数字资产继承路径。 在鸿蒙世界中,我们每个人在每台设备、应用…...

阿里云NAS文件存储基本介绍与购买使用
文章目录 1.NAS文件存储基本概念1.1.什么是NAS文件存储1.2.NAS的应用场景1.3.NAS、OSS、EBS的区别 2.购买NAS文件存储2.1.开通NAS服务2.2.创建NAS文件系统2.3.配置NAS文件系统属性2.4.查看购买的NAS服务 3.NAS文件存储基本使用3.1.修改NAS文件系统默认的名称3.2.NAS的权限组3.3…...

大模型使用——超算上部署LLAMA-2-70B-Chat
大模型使用——超算上部署LLAMA-2-70B-Chat 前言 1、本机为Inspiron 5005,为64位,所用操作系统为Windos 10。超算的操作系统为基于Centos的linux,GPU配置为A100,所使用开发环境为Anaconda。 2、本教程主要实现了在超算上部署LLAM…...

机器学习笔记:李宏毅ChatGPT课程1:刨析ChatGPT
ChatGPT——Chat Generative Pre-trained Transformer 1 文字接龙 每次输出一个概率分布,根据概率sample一个答案 ——>因为是根据概率采样,所以ChatGPT每次的答案是不一样的(把生成式学习拆分成多个分类问题)将生成的答案加到…...
Llama 2 with langchain项目详解(三)
Llama 2 with langchain项目详解(三) 17.3 Llama 2 with langchain基础 本节讲解在LangChain中使用Llama 2模型的基础知识,展示如何运行LangChain的代码,及在云端运行Llama 2的700亿模型。 首先,使用Python的pip管理器安装一系列库,包括huggingface/transformers、datase…...
牛客 AB30 排序(快排模板)
描述 给定一个长度为 n 的数组,请你编写一个函数,返回该数组按升序排序后的结果。 数据范围: 0≤�≤11030≤n≤1103,数组中每个元素都满足 0≤���≤1090≤val≤109 要求࿱…...

【Linux旅行记】第一个小程序“进度条“!
文章目录 一、预备知识1.1回车换行1.2缓冲区 二、倒计时三、进度条3.1普通版本源代码3.2高级版本源代码 🍀小结🍀 🎉博客主页:小智_x0___0x_ 🎉欢迎关注:👍点赞🙌收藏✍️留言 &…...

DeepMind将AI用于可控核聚变:将等离子体形状模拟精度提高65%
近日,英国AI公司DeepMind宣布取得了一项新的突破,成功实现了AI可控核聚变。这一技术能够在高温等离子体环境下实现精准放电,为核聚变技术的发展提供了新的思路和创新。 长期以来,相关领域的科学家们,一直在寻找清洁、取…...

Scrum是什么意思,Scrum敏捷项目管理工具有哪些?
一、什么是Scrum? Scrum是一种敏捷项目管理方法,旨在帮助团队高效地开展软件开发和项目管理工作。 Scrum强调迭代和增量开发,通过将项目分解为多个短期的开发周期(称为Sprint),团队可以更好地应对需求变…...
【从零单排Golang】第十三话:使用WaitGroup等待多路并行的异步任务
在后端开发当中,经常会遇到这样的场景:请求给了批量的输入,对于每一个输入,我们都要给外部发请求等待返回,然后才能继续其它自己的业务逻辑。在这样的case下,如果每一个输入串行处理的话,那么很…...

WSL2安装CentOS7和CentOS8
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、下载ZIP包?二、安装1.打开Windows子系统支持2.安装到指定位置3.管理虚拟机4.配置虚拟机1.配置国内源2.安装软件3.安装第三方源 5.配置用户1.创建…...

不平衡电网条件下基于变频器DG操作的多目标优化研究(Matlab代码Simulink实现)
目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码&Simulink实现&文章讲解 💥1 概述 文献来源: 最近,利用并网转换器(GCC)克服电网故障并支撑电网电压已…...
【Leetcode】(自食用)简单题||单词数
step by step. 题目: 统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。 请注意,你可以假定字符串里不包括任何不可打印的字符。 示例: 输入: "Hello, my name is John" 输出: 5 解释: 这里的单词是指连续的不是空格…...

C语言代码的x86-64汇编指令分析过程记录
先通过Xcode创建一个terminal APP,语言选择C。代码如下: #include <stdio.h>int main(int argc, const char * argv[]) {int a[7]{1,2,3,4,5,6,7};int *ptr (int*)(&a1);printf("%d\n",*(ptr));return 0; } 在return 0处打上断点&…...

基于springboot+vue的房屋租赁系统(前后端分离)
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...
Python文件读写操作详解:从基础到高级
摘要:文件读写是Python编程中常见的操作之一。本文将介绍Python中文件读写的基础知识,包括打开文件、读取文件内容、写入文件、关闭文件等基本操作。此外,还将探讨一些高级文件读写技术,如使用上下文管理器、处理异常、使用with语…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...

2025-05-08-deepseek本地化部署
title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek:小白也能轻松搞定! 如何给本地部署的 DeepSeek 投喂数据,让他更懂你 [实验目的]:理解系统架构与原…...