minio文件存储

540 阅读1分钟

Minio是用来存储文件的服务,代替FastDFS,和阿里云OSS差不多,本文介绍搭建和工具类

version: '3.1'
services:
  minio:
    image: minio/minio
    container_name: minio
    restart: always
    ports:
      - 9000:9000
    command: server /data  # 指定容器中的目录/data
    environment:
      MINIO_ACCESS_KEY: minio  # 管理后台用户名,最小3个字符
      MINIO_SECRET_KEY: minioxxx  # 密码,最小8个字符
    volumes:
      - ./data:/data
      - ./config:/root/.minio/

启动后,访问IP:9000,输入access keysecret key登录

点击右下角+号,选择Create bucket,输入存储桶的名称,创建成功后在左边会显示新创建的存储桶

默认情况下这个存储桶中的文件外部访问不了,需要修改策略,点击上图的三个小点,选择Edit policy

输入*号,选择Read Only,点击Add即可,到这里Minio配置完毕

下面提供工具类,可以在Minio官网上找到各种常用语言的SDK

Setting类

@Data
public class MinioSetting {

    private String accessKey;
    private String secretKey;
    private String bucket;
    private String host;
    private Integer port;
    private Boolean ssl;

}

Config类

@Configuration
public class MinioConfig {
    @Bean
    @ConfigurationProperties(prefix = "minio")
    public MinioSetting minioSetting() {
        return new MinioSetting();
    }
}

工具类

public class MinioUtil {

    @Autowired
    private MinioSetting setting;

    private static String bucketName;
    private static MinioClient client;
    private static Map<String, String> contentTypes;

    @PostConstruct
    private void init() {
        client = MinioClient.builder()
                .endpoint(setting.getHost(), setting.getPort(), setting.getSsl())
                .credentials(setting.getAccessKey(), setting.getSecretKey())
                .build();

        bucketName = setting.getBucket();

        contentTypes = new HashMap<>(20);
        contentTypes.put("html", "text/html");
        contentTypes.put("htm", "text/html");
        contentTypes.put("txt", "text/plain");
        contentTypes.put("xml", "text/xml");
        contentTypes.put("gif", "image/gif");
        contentTypes.put("jpeg", "image/jpeg");
        contentTypes.put("jpg", "image/jpeg");
        contentTypes.put("png", "image/png");
        contentTypes.put("json", "application/json");
        contentTypes.put("pdf", "application/pdf");
        contentTypes.put("mp4", "video/mp4");
    }

    /**
     * 上传文件
     * @param key
     * @param is
     * @param size
     * @throws Exception
     */
    public static void put(String key, InputStream is, long size) throws Exception {
        PutObjectArgs args = PutObjectArgs.builder()
                .bucket(bucketName)
                .object(key)
                .stream(is, size, -1)
                .contentType(getContentType(key))
                .build();
        client.putObject(args);
    }

    /**
     * 获取文件meta信息,返回null就表示文件不存在
     * @param key
     * @return
     * @throws Exception
     */
    public static ObjectStat stat(String key) throws Exception {
        StatObjectArgs args = StatObjectArgs.builder()
                .bucket(bucketName)
                .object(key)
                .build();
        try {
            return client.statObject(args);
        } catch (ErrorResponseException e) {
            return null;
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * 获取指定文件内容
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] get(String key) throws Exception {
        GetObjectArgs args = GetObjectArgs.builder()
                .bucket(bucketName)
                .object(key)
                .build();
        InputStream is = client.getObject(args);

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int n = 0;
        while (-1 != (n = is.read(buffer))) {
            os.write(buffer, 0, n);
        }
        is.close();
        return os.toByteArray();
    }

    /**
     * 删除指定文件
     * @param key
     * @throws Exception
     */
    public static void remove(String key) throws Exception {
        RemoveObjectArgs args = RemoveObjectArgs.builder()
                .bucket(bucketName)
                .object(key)
                .build();
        client.removeObject(args);
    }

    /**
     * 删除多个文件
     * @param keys
     * @return
     * @throws Exception
     */
    public static Iterable<Result<DeleteError>> remove(List<String> keys) throws Exception {
        List<DeleteObject> objects = new LinkedList<>();
        keys.forEach(it -> {
            objects.add(new DeleteObject(it));
        });

        RemoveObjectsArgs args = RemoveObjectsArgs.builder()
                .bucket(bucketName)
                .objects(objects)
                .build();
        return client.removeObjects(args);
    }

    /**
     * 获取contentType
     * @param key
     * @return
     */
    public static String getContentType(String key) {
        String ext = StringUtils.getFileExt(key);
        if (contentTypes.containsKey(ext)) {
            return contentTypes.get(ext);
        }
        return "application/octet-stream";
    }

    public static String getUploadUrl(String ext) {
        StringBuilder sb = new StringBuilder();
        sb.append("group/");
        sb.append(TimeUtils.format(new Date(), "yyyy-MM")).append("/");
        sb.append(StringUtils.randomNumberAndString(30)).append(".").append(ext);
        return sb.toString();
    }

}