文章目录
- 几种常用的文件存储
- 安装和使用minio
- SpringBoot整合minio
基本所有的软件项目都会需要文件存储功能,图片、视频存储。
几种常用的文件存储
经常用的几种方案,直接存在本地文件夹,开发一个简单的系统当然没有问题。随机系统所需的资源变多,这种情况显然是不可能的。这种适合做一个简单的demo,毕设之类的的系统。
使用第三方的存储服务,如阿里云的oss,十分的方便管理。但是是收费的,如果经费充足也可以考虑。
使用HDFS ,分布式文件存储放方案,大数据领域的文件存储框架,过程配置很繁琐,对于新手来说很不友好。
minio 是一个非常轻量的服务,可以很简单的和其他应用的结合使用,它兼容亚马逊 S3 云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等。
还提供了许多语言的SDK,开发较为方便。
MinIO集群采用去中心化共享架构,每个结点是对等关系,通过Nginx可对MinIO进行负载均衡访问。
安装和使用minio
在linux上面配置mioio过于繁琐。在windows上面也可以运行。
minio的官网:dl.min.io/server/minio/release/windows-amd64/
首先下载minio,下载后是一个.exe文件
在cmd窗口中运行
//minio.exe server 启动服务器 后面是对应的节点也就是数据存储的位置,如果上线了就是服务器的地址
minio.exe server E:\develop\data\data1 E:\develop\data\data2 E:\develop\data\data3 E:\develop\data\data4
访问mino
在浏览器中输入:http://localhost:9000 跳转到登录页面 账号和密码都是 minioadmin
登录进去后;
设置bucket为公有public,可以外部进行访问的。
文件的地址就是 ip地址+端口号9000+文件的相对地址
SpringBoot整合minio
1.导入minio的maven坐标。
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.3</version>
</dependency>
2.配置yml文件
minio:endpoint: http://127.0.0.1:9000 #文件的前缀 数据存储文件地址应该是相对地址,便于以后更换服务器accessKey: minioadminsecretKey: minioadminbucket:files: mediafilesvideofiles: video
在springBootTest中编写程序
//创建一个minioClient
static MinioClient minioClient =MinioClient.builder().endpoint("http://127.0.0.1:9000").credentials("minioadmin", "minioadmin").build();
3.注册bean,需要用minclient。
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;//注入到bean中去
@Configuration
public class MinioConfig {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}
}
FileController
import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import com.njitzx.service.FileService;
import com.njitzx.util.Result;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.File;@RestController
@RequestMapping(value = "/upload")
@Slf4j
public class FileController {private String bucket = "bucket";@Autowiredprivate FileService fileService;@Value("${minio.endpoint}")private String endpoint;/*** 要有一个文件存储的目录?如果判断文件是否已经存在*//*** file 前端传过来的文件*/@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)public Result<String> upload(@RequestParam("file") MultipartFile file) throws Exception {log.info("开始上传文件");System.out.println(file.getOriginalFilename());String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));File tempFile = File.createTempFile("temp", suffix);file.transferTo(tempFile);String floadName = fileService.upload(tempFile);String url = endpoint + "/" + bucket + "/" + floadName;return Result.success(url);}public static String getMimeType(String extension) {if (extension == null)extension = "";//根据扩展名取出mimeTypeContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);//通用mimeType,字节流String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;if (extensionMatch != null) {mimeType = extensionMatch.getMimeType();}return mimeType;}/*** 删除文件*/
}
import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import com.njitzx.service.FileService;import io.minio.MinioClient;
import io.minio.UploadObjectArgs;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;import java.io.File;import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;@Service
@Slf4j
public class FileServiceImpl implements FileService {@AutowiredMinioClient minioClient;private String bucket = "bucket";@Overridepublic String upload(File tempFile) {String filename = tempFile.getName();System.out.println(filename);String extension = filename.substring(filename.lastIndexOf("."));String objectname = getDefaultFolderPath() + getFileMd5(tempFile) + extension;System.out.println(objectname);try {UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder().bucket(bucket).object(objectname).filename(tempFile.getAbsolutePath()).contentType(getMimeType(extension)).build();minioClient.uploadObject(uploadObjectArgs);log.info("上传成功");return objectname;} catch (Exception e) {throw new RuntimeException(e);}}public static String getMimeType(String extension) {if (extension == null)extension = "";//根据扩展名取出mimeTypeContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);//通用mimeType,字节流String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;if (extensionMatch != null) {mimeType = extensionMatch.getMimeType();}return mimeType;}public static String getFileMd5(File file) {try {FileInputStream fileInputStream = new FileInputStream(file);String filemd5 = DigestUtils.md5DigestAsHex(fileInputStream);return filemd5;} catch (Exception e) {throw new RuntimeException(e.getMessage());}}private String getDefaultFolderPath() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String folder = sdf.format(new Date()).replaceAll("-", "/") + "/";return folder;}
}