SpringBoot整合Minio

2023-10-26

1、引入依赖

POM文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <parent>
        <artifactId>spring-boot</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.7.5</version>
    </parent>
    <groupId>org.example</groupId>
    <artifactId>MinioDemo</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.7.5</version>
        </dependency>
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <version>2.7.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>

</project>

核心依赖:

   <dependency>
        <groupId>io.minio</groupId>
        <artifactId>minio</artifactId>
        <version>8.5.1</version>
    </dependency>辅助依赖:
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.4</version>
    </dependency>

2、Minio配置类

  • 配置文件

min:
  io:
    endpoint: http://ip:port
    accessKey: minioadmin
    secretKey: minioadmin
    bucket: test
    imageType: .jpeg
spring:
  application:
    name: minioDmeo
  servlet:
    multipart:
      max-file-size: 5MB
      max-request-size: 15MB
server:
  port: 8080
package MinioDemo.config;

import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Data
@Component
public class MinIoConfig {

    @Value("${min.io.endpoint}")
    private String endpoint;

    @Value("${min.io.accessKey}")
    private String accessKey;

    @Value("${min.io.secretKey}")
    private String secretKey;

    @Bean
    public MinioClient minioClient(){
        return MinioClient.builder().endpoint(endpoint).credentials(accessKey,secretKey).build();
    }

}

3、Minio工具类

package MinioDemo.utils;

import MinioDemo.dto.MinIoUploadResDTO;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.SneakyThrows;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

@Component
public class MinIoUtils {

    @Resource
    private MinioClient client;

    private static final String SEPARATOR_DOT = ".";

    private static final String SEPARATOR_ACROSS = "-";

    private static final String SEPARATOR_STR = "";

    // 存储桶名称
    private static final String chunkBucKet = "img";

    /**
     * 不排序
     */
    public final static boolean NOT_SORT = false;

    /**
     * 排序
     */
    public final static boolean SORT = true;

    /**
     * 默认过期时间(分钟)
     */
    private final static Integer DEFAULT_EXPIRY = 60;
    

    /**
     * @param bucketName
     * @return boolean
     * @Description 判断 bucket是否存在
     * @author exe.wangtaotao
     * @date 2020/10/21 16:33
     */
    public boolean bucketExists(String bucketName) {
        try {
            return client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 创建存储桶
     * 创建 bucket
     *
     * @param bucketName
     */
    public void makeBucket(String bucketName) {
        try {
            boolean isExist = bucketExists(bucketName);
            if (!isExist) {
                client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param
     * @return java.util.List<java.lang.String>
     * @Description 获取文件存储服务的所有存储桶名称
     * @author exe.wangtaotao
     * @date 2020/10/21 16:35
     */
    public List<String> listBucketNames() {
        List<Bucket> bucketList = listBuckets();
        List<String> bucketListName = new ArrayList<>();
        for (Bucket bucket : bucketList) {
            bucketListName.add(bucket.name());
        }
        return bucketListName;
    }

    /**
     * @return java.util.List<io.minio.messages.Bucket>
     * @Description 列出所有存储桶
     */
    @SneakyThrows
    private List<Bucket> listBuckets() {
        return client.listBuckets();
    }


    /**
     * 获取对象文件名称列表
     *
     * @param bucketName 存储桶名称
     * @param prefix     对象名称前缀(文件夹 /xx/xx/xxx.jpg 中的 /xx/xx/)
     * @return objectNames
     */
    public List<String> listObjectNames(String bucketName, String prefix) {
        return listObjectNames(bucketName, prefix, NOT_SORT);
    }


    /**
     * 获取对象文件名称列表
     *
     * @param bucketName 存储桶名称
     * @param prefix     对象名称前缀(文件夹 /xx/xx/xxx.jpg 中的 /xx/xx/)
     * @param sort       是否排序(升序)
     * @return objectNames
     */
    @SneakyThrows
    public List<String> listObjectNames(String bucketName, String prefix, Boolean sort) {

        boolean flag = bucketExists(bucketName);
        if (flag) {

            ListObjectsArgs listObjectsArgs;
            if (null == prefix) {
                listObjectsArgs = ListObjectsArgs.builder()
                        .bucket(bucketName)
                        .recursive(true)
                        .build();
            } else {
                listObjectsArgs = ListObjectsArgs.builder()
                        .bucket(bucketName)
                        .prefix(prefix)
                        .recursive(true)
                        .build();
            }
            Iterable<io.minio.Result<Item>> chunks = client.listObjects(listObjectsArgs);
            List<String> chunkPaths = new ArrayList<>();
            for (io.minio.Result<Item> item : chunks) {
                chunkPaths.add(item.get().objectName());
            }
            if (sort) {
                chunkPaths.sort(new Str2IntComparator(false));
            }
            return chunkPaths;
        }
        return new ArrayList<>();
    }

    /**
     * 在桶下创建文件夹,文件夹层级结构根据参数决定
     *
     * @param bucket 桶名称
     * @param WotDir 格式为 xxx/xxx/xxx/
     */
    @SneakyThrows
    public String createDirectory(String bucket, String WotDir) {
        if (!this.bucketExists(bucket)) {
            return null;
        }
        client.putObject(PutObjectArgs.builder().bucket(bucket).object(WotDir).stream(
                new ByteArrayInputStream(new byte[]{}), 0, -1)
                .build());
        return WotDir;
    }


    /**
     * 删除一个文件
     *
     * @param bucketName
     * @param objectName
     */
    @SneakyThrows
    public boolean removeObject(String bucketName, String objectName) {

        if (!bucketExists(bucketName)) {
            return false;
        }
        client.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build());
        return true;
    }

    /**
     * @param bucketName
     * @param objectNames
     * @return java.util.List<java.lang.String>
     * @Description 删除指定桶的多个文件对象, 返回删除错误的对象列表,全部删除成功,返回空列表
     * @author exe.wangtaotao
     * @date 2020/10/21 16:43
     */
    @SneakyThrows
    public List<String> removeObjects(String bucketName, List<String> objectNames) {
        if (!bucketExists(bucketName)) {
            return new ArrayList<>();
        }
        List<DeleteObject> deleteObjects = new ArrayList<>(objectNames.size());
        for (String objectName : objectNames) {
            deleteObjects.add(new DeleteObject(objectName));
        }
        List<String> deleteErrorNames = new ArrayList<>();
        Iterable<io.minio.Result<DeleteError>> results = client.removeObjects(
                RemoveObjectsArgs.builder()
                        .bucket(bucketName)
                        .objects(deleteObjects)
                        .build());
        for (io.minio.Result<DeleteError> result : results) {
            DeleteError error = result.get();
            deleteErrorNames.add(error.objectName());
        }
        return deleteErrorNames;
    }


    /**
     * 获取访问对象的外链地址
     * 获取文件的下载url
     *
     * @param bucketName 存储桶名称
     * @param objectName 对象名称
     * @param expiry     过期时间(分钟) 最大为7天 超过7天则默认最大值
     * @return viewUrl
     */
    @SneakyThrows
    public String getObjectUrl(String bucketName, String objectName, Integer expiry) {
        expiry = expiryHandle(expiry);
        return client.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucketName)
                        .object(objectName)
                        .expiry(expiry)
                        .build()
        );
    }


    /**
     * 创建上传文件对象的外链
     *
     * @param bucketName 存储桶名称
     * @param objectName 欲上传文件对象的名称
     * @return uploadUrl
     */
    public String createUploadUrl(String bucketName, String objectName) {
        return createUploadUrl(bucketName, objectName, DEFAULT_EXPIRY);
    }

    /**
     * 创建上传文件对象的外链
     *
     * @param bucketName 存储桶名称
     * @param objectName 欲上传文件对象的名称
     * @param expiry     过期时间(分钟) 最大为7天 超过7天则默认最大值
     * @return uploadUrl
     */
    @SneakyThrows
    public String createUploadUrl(String bucketName, String objectName, Integer expiry) {
        expiry = expiryHandle(expiry);
        return client.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.PUT)
                        .bucket(bucketName)
                        .object(objectName)
                        .expiry(expiry)
                        .build()
        );
    }

    /**
     * 文件下载
     *
     * @param fileName 文件名
     * @return InputStream
     */
    public void downLoadFile(HttpServletResponse response,String fileName) {
       /* InputStream inputStream = null;
        try {
            StatObjectResponse statObjectResponse = client.statObject(StatObjectArgs.builder().bucket(chunkBucKet).object(fileName).build());
            if (statObjectResponse.size() > 0) {
                inputStream = client.getObject(GetObjectArgs.builder().bucket(chunkBucKet).object(fileName).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return inputStream;*/
        try(InputStream ism = new BufferedInputStream(client.getObject(GetObjectArgs.builder()
                .bucket(chunkBucKet)
                .object(fileName).build()))) {
            // 调用statObject()来判断对象是否存在。
            // 如果不存在, statObject()抛出异常,
            // 否则则代表对象存在
            client.statObject(StatObjectArgs.builder()
                    .bucket(chunkBucKet)
                    .object(fileName).build());
            byte buf[] = new byte[1024];
            int length = 0;
            response.reset();
            //Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。
            // Content-disposition其实可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,
            // 文件直接在浏览器上显示或者在访问时弹出文件下载对话框。
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/x-msdownload");
            response.setCharacterEncoding("utf-8");
            OutputStream osm = new BufferedOutputStream(response.getOutputStream());
            while ((length = ism.read(buf))>0) {
                osm.write(buf,0, length);
            }
            osm.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    /**
     * 批量下载
     *
     * @param directory
     * @return
     */
    @SneakyThrows
    public List<String> downLoadMore(String bucket, String directory) {
        Iterable<io.minio.Result<Item>> objs = client.listObjects(ListObjectsArgs.builder().bucket(bucket).prefix(directory).useUrlEncodingType(false).build());
        List<String> list = new ArrayList<>();
        for (io.minio.Result<Item> result : objs) {
            String objectName = null;
            objectName = result.get().objectName();
            StatObjectResponse statObject = client.statObject(StatObjectArgs.builder().bucket(bucket).object(objectName).build());
            if (statObject != null && statObject.size() > 0) {
                String fileurl = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucket).object(statObject.object()).method(Method.GET).build());
                list.add(fileurl);
            }
        }
        return list;
    }


    /**
     * @param multipartFile
     * @param bucketName
     * @param directory image/
     * @return java.lang.String
     * @Description 文件上传
     * @author exe.wangtaotao
     * @date 2020/10/21 13:45
     */
    public MinIoUploadResDTO upload(MultipartFile multipartFile, String bucketName, String directory) throws Exception {
        if (!this.bucketExists(bucketName)) {
            this.makeBucket(bucketName);
        }
        InputStream inputStream = multipartFile.getInputStream();
        directory = Optional.ofNullable(directory).orElse("");
        String minFileName = directory + minFileName(multipartFile.getOriginalFilename());
        System.out.println(minFileName);
        System.out.println(multipartFile.getContentType());
        //上传文件到指定目录
        client.putObject(PutObjectArgs.builder()
                .bucket(bucketName)
                .object(minFileName)
                .contentType(multipartFile.getContentType())
                .stream(inputStream, inputStream.available(), -1)
                .build());
        inputStream.close();
        // 返回生成文件名、访问路径
        return new MinIoUploadResDTO(minFileName, getObjectUrl(bucketName, minFileName, DEFAULT_EXPIRY));
    }

    public MinIoUploadResDTO uploadByBytes(byte[] bytes,String fileName, String bucketName, String directory) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        fileName =directory+"/"+fileName;
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectWriteResponse objectWriteResponse = client.putObject(PutObjectArgs.builder().bucket(bucketName)
                .object(fileName)
                .contentType("image/jpeg")
                .stream(byteArrayInputStream, byteArrayInputStream.available(), -1)
                .build());
        return new MinIoUploadResDTO(fileName,getObjectUrl(bucketName,fileName,DEFAULT_EXPIRY));
    }


    /**
     * @param response
     * @return java.lang.String
     * @Description 下载文件
     * @author exe.wangtaotao
     * @date 2020/10/21 15:18
     */
    public void download(HttpServletResponse response, String bucketName, String minFileName)  {
        InputStream fileInputStream = null;
        try {
            fileInputStream = client.getObject(GetObjectArgs.builder()
                    .bucket(bucketName)
                    .object(minFileName).build());
//            response.setHeader("Content-Disposition", "attachment;filename=" + minFileName);
//            response.setContentType("application/force-download");
            response.setContentType("image/jpeg");
            response.setCharacterEncoding("UTF-8");
            IOUtils.copy(fileInputStream, response.getOutputStream());
        } catch (ErrorResponseException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | XmlParserException | InsufficientDataException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
    /**
     * @param originalFileName
     * @return java.lang.String
     * @Description 生成上传文件名
     * @author exe.wangtaotao
     * @date 2020/10/21 15:07
     */
    private String minFileName(String originalFileName) {
        String suffix = originalFileName;
        if (originalFileName.contains(SEPARATOR_DOT)) {
            suffix = originalFileName.substring(originalFileName.lastIndexOf(SEPARATOR_DOT));
        }
        return UUID.randomUUID().toString().replace(SEPARATOR_ACROSS, SEPARATOR_STR).toUpperCase() + suffix;
    }


    /**
     * 将分钟数转换为秒数
     *
     * @param expiry 过期时间(分钟数)
     * @return expiry
     */
    private static int expiryHandle(Integer expiry) {
        expiry = expiry * 60;
        if (expiry > 604800) {
            return 604800;
        }
        return expiry;
    }

    static class Str2IntComparator implements Comparator<String> {
        private final boolean reverseOrder; // 是否倒序

        public Str2IntComparator(boolean reverseOrder) {
            this.reverseOrder = reverseOrder;
        }

        @Override
        public int compare(String arg0, String arg1) {
            Integer intArg0 = Integer.parseInt(arg0.substring(arg0.indexOf("/") + 1, arg0.lastIndexOf(".")));
            Integer intArg1 = Integer.parseInt(arg1.substring(arg1.indexOf("/") + 1, arg1.lastIndexOf(".")));
            if (reverseOrder) {
                return intArg1 - intArg0;
            } else {
                return intArg0 - intArg1;
            }
        }
    }

}

4、测试类

    @GetMapping("/upload2")
    public void test() throws Exception {
        File file = new File("D:\\浏览器下载\\boy1.jpg");
        InputStream inputStream = new FileInputStream(file);
        MultipartFile multipartFile = getMultipartFile(file);
        MinIoUploadResDTO test = minIoUtils.upload(multipartFile, "test", "");
        System.out.println(test.getMinFileUrl());
    }
    public static MultipartFile getMultipartFile(File file) {
        FileItem item = new DiskFileItemFactory().createItem("file"
                , MediaType.MULTIPART_FORM_DATA_VALUE
                , true
                , file.getName());
        try (InputStream input = new FileInputStream(file);
             OutputStream os = item.getOutputStream()) {
            // 流转移
            IOUtils.copy(input, os);
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid file: " + e, e);
        }
        return new CommonsMultipartFile(item);
    }
   

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot整合Minio 的相关文章

  • 在 libgdx 中批处理多维数据集时出现问题

    我正在尝试开发一款游戏 在屏幕上渲染多达 300 个立方体 为每个多维数据集创建新的 modelInstance 时 modelBatch 的性能非常糟糕 据我所知 没有 3d 批处理可以将所有立方体批处理到一次绘制调用 所以我拼命地尝试以
  • SharePoint 2010 Web 服务上的 Java JBoss 401 错误

    我的代码在 Eclipse IDE 中测试时运行成功 我正在使用生成的 Copy wsdl 通过 Web 服务连接到 MS SharePoint 2010 当我在 JBoss 服务器上部署代码 运行 Adob e LifeCycle 时 我
  • 检查两个日期周期是否重叠[重复]

    这个问题在这里已经有答案了 我有两个日期范围 start1 end1 gt gt date1 start2 end2 gt gt date2 我想检查两个日期是否重叠 我的流程图我假设 运算符对于比较是有效的 boolean isOverL
  • Netbeans 雷达插件配置

    我使用的是 Netbeans 8 0 1 在提交到 SVN 之前 我需要从 IDE 运行并检查 SonarQube 分析 我已经安装了 Netbeans Radar 插件 用于启动本地分析并检查结果 这个插件有一个名为 Get Issues
  • 将 Swing 集成到简单的文本冒险游戏中

    我对 Java 中的一些中级概念相当陌生 最近 我制作了一款名为 DazzleQuest 的文本冒险游戏 它完全在开发者控制台 终端中运行 它涉及到我的朋友作为角色 所以我想向他们展示它 并通过将命令行的功能和控制台的输出转移到一个简单的
  • rmi类找不到异常

    我使用 java rmi 编写了一个简单的项目并导出到可执行 jar 文件 当我尝试运行它时 有时会出现异常 有时会起作用 当我指定 Djava rmi server codebase file serverClasses 时 它似乎没有正
  • Cognito SRP 身份验证 JAVA SDK

    我正在尝试使用 Cognito 验证 Java 应用程序 我在Python中使用了warrant库 效果非常好 但我现在想在java中做同样的事情 我的 Python 函数用于身份验证warrant https github com cap
  • 控制启动时的竞争条件

    我有一些代码想要执行一些一次性初始化 但这段代码没有明确的生命周期 因此在初始化完成之前 我的逻辑可能会被多个线程调用 所以 我想基本上确保我的逻辑代码 等待 直到初始化完成 这是我的第一次剪辑 public class MyClass p
  • Spring MVC:@ResponseBody 中的重定向

    我想在 spring mvc 方法中重定向到另一个 jsp 我不想使用像 window location replace url 这样的 JavaScript 方法 我的方法 RequestMapping value loginUser m
  • 不带破折号的 CliBuilder 参数

    使用 Groovy CliBuilder 理想情况下我希望有一个命令行 如下所示 MyProgram groovy CommandName arg1 arg2 arg3 是否可以使用 CliBuilder 解析提取 CommandName
  • xclock 工作,X11 DISPLAY 设置但仍然 java.awt.HeadlessException:

    获取 java awt HeadlessException 似乎是一个非常常见的问题 并且 中已经讨论过 以下问题 没有 X11 DISPLAY 变量 这是什么意思 https stackoverflow com questions 662
  • 在字节数组上进行右位旋转/循环移位的最快方法是什么

    如果我有数组 01101111 11110000 00001111 111 240 15 移位 1 位的结果是 10110111 11111000 00000111 183 248 7 数组大小不固定 移位范围为 1 到 7 含 目前我有以
  • Jetty 提供静态内容所需的最少文件集?

    背景 免责声明 I have veryJava 经验很少 我们之前在 Ant 构建期间使用了 Jetty 6 的包装版本来处理按需静态内容 JS CSS 图像 HTML 因此我们可以使用 PhantomJS 针对 HTTP 托管环境运行单元
  • 在 XSSF 工作簿上设置密码保护

    我想为使用 poi 3 14 创建的 xlsx 文件添加密码保护 该文档声称 这是可能的 http poi apache org cryption html http poi apache org encryption html 使用我尝试
  • toArray 与预先确定大小的数组

    使用时ar toArray new String ar size 安卓工作室3 2 1警告预先确定大小的数组并建议空数组 有两种方式将集合转换为数组 使用 预先确定大小的数组 如 c toArray new String c size 或使
  • CompletableFuture SupplyAsync

    我刚刚开始探索 Java 8 的一些并发特性 让我有点困惑的一件事是这两个静态方法 CompletableFuture
  • 如何查找类路径中具有指定名称的所有资源?

    我想列出类路径中具有特定名称的所有文件 我预计会发生多次 因此Class getResource String 不管用 基本上 我必须识别类路径中任何位置具有特定名称 例如 xyz properties 的所有文件 然后累积读取其中的元数据
  • 在服务器上创建 Zip 文件并使用 java 下载该 zip

    我从 mkyong 获得了以下代码 用于在本地压缩文件 但是 我的要求是在服务器上压缩文件并需要下载它 任何人都可以帮忙吗 代码写入zip文件 public void zipFiles File contentFile File navFi
  • 不幸的是 Project_Name 已停止

    我有一个简单的应用程序 您可以在文本视图中输入文本并按提交 它会在另一个活动中显示文本 然而 当我按下提交时 给我消息 不幸的是 发送已停止 我查看了SO上的其他线程 但是不幸的是 myfirstproject 在 java 中停止工作错误
  • Java Media API:java media api 下载

    我在哪里可以找到javax media jar 文件 在sun站点它下载一个安装程序 有没有可用的java媒体jar 没有 javax media 具体是 jar 文件 该包位于 jmf jar 文件中 您需要运行安装程序并取出 jar 或

随机推荐

  • 多进程及多线程的区别

    一 两者区别 多进程和多线程的主要区别是 线程是进程的子集 部分 一个进程可能由多个线程组成 多进程的数据是分开的 共享复杂 需要用IPC 但同步简单 多线程共享进程数据 共享简单 但同步复杂 1 多进程 进程是程序在计算机上的一次执行活动
  • Java-单链表相关总结

    链表基类 author Q sir date 2021 06 08 desc 仅限本类操作 有些方法未加兼容及拓展 class Node Node next int data public Node int data this data d
  • 【满分】【华为OD机试真题2023 JAVA&JS】简单的自动曝光

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 简单的自动曝光 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 一个图像有n个像素点 存储在一个长度为n的数组img里 每个像素点的取值范围 0 255 的正整数
  • Locust性能测试-分布式执行的方法(ok)

    来源 https www cnblogs com yoyoketang p 11681370 html https www cnblogs com kaibindirver p 11773334 html 前言 使用Locust进行性能测试
  • 腾讯云服务器被DDOS攻击解决办法

    腾讯云是国内仅此次阿里云的云服务商 很多站长朋友都使用他们家云服务器 自然被DDOS攻击的也不少 今天来介绍下使用腾讯云服务器被DDOS攻击的解决办法 一 购买腾讯高防IP 也称腾讯大禹BGP高防IP 是一个运行在腾讯云内网的高防IP服务
  • 第二章:简单古典密码(及其五元组)

    简单古典密码及其五元组 编制密码的基本原理和基本方法称为密码法 基本的密码法主要有移位 也称为置换 代替 和加减三种 在许多书上只是介绍置换和代替 在密码发展的初级阶段 他们都曾经独立地作为加密算法对明文信息进行加密 移位密码 移位密码是按
  • -bash: /big_date/jdk1.8.0_333/bin/java: /lib/ld-linux.so.2: bad ELF interpreter: 没有那个文件或目录

    自说 在CentOS7中搭建环境中 解压过java1 8版本时 配置好环境变量进行测试java版本时出现以下错误 出现这种情况的原因是因为当前环境缺少相关依赖包 glibc glibc 简单来说 glibc是gnu发布的libc库 即c运行
  • 毕业设计-基于SSM的网上商城系统

    项目编号 D09 项目名称 基于SSM的网上商城系统 项目类型 Java web项目 JavaEE 当前版本 V1 0 0版本 用户类型 有用户和管理员 双角色 项目架构 B S架构 设计思想 MVC 开发语言 Java语言 前端技术 La
  • js——网址动态拼接参数

    案例 你可以使用字符串拼接的方式来动态拼接参数到网址上 在这种情况下 你可以使用加号运算符来连接字符串 并使用变量来表示参数的值 下面是一个示例代码 let aaa http www baidu com let xxx 1 let yyy
  • 对于一个采用字符数组存放的字符串str,设计一个递归算法StrLength(char *str)求其字符个数(长度)。递归求字符串长度

    递归求字符串长度 需要的就是将数组看成指针 一步一步走下去 int StrLength char str char p str if p 0 return 0 else return StrLength p 1 努力加油a啊 o
  • 走出软件作坊

    这本书 对于小开发者真的是实用手册 关于如何与老板相处 如何做人 如何做技术 对于在小企业工作的人来说 真的不错 2014 7 11
  • c#自定义消息事件

    自定义消息 public class CustomEventArgs EventArgs public readonly string msg public CustomEventArgs string msg this msg msg 自
  • 设计模式之桥接模式(Bridge模式)

    一 模式动机 设想如果要绘制矩形 圆形 椭圆 正方形 我们至少需要4个形状类 但是如果绘制的图形需要具有不同的颜色 如红色 绿色 蓝色等 此时至少有如下两种设计方案 第一种设计方案是为每一种形状都提供一套各种颜色的版本 第二种设计方案是根据
  • 云服务器搭建神器JupyterLab(多图)

    云服务器搭建神器JupyterLab 多图 JupyterLab是一个交互式的开发环境 其用于应对包含着notebook 代码以及数据的工作场景 1 前言 如果说vim是编辑器之神 那么JupyterLab就是笔记本之神 从2017年开始我
  • 极端天气下的目标检测与测距算法

    更多视觉额自动驾驶项目请见 小白学视觉 自动驾驶项目 本文主要工作 科技的发展与进步促使自动驾驶车辆逐渐成为全球汽车产业发展的重要战略 方向 但自动驾驶车辆面对如 大雨 大雾 大雪等极端环境时 智能汽车图像 采集与处理系统将面临巨大挑战 并
  • 基于Python的socket库实现通信功能

    目录 1 前言 2 技术介绍 1 socket 2 Python的socket库 3 系统实现 1 服务端 server py 2 客户端1 client1 py 3 客户端2 client2 py 4 系统功能演示 1 启动服务端和客户端
  • idea配置maven教程

    1 下载maven 下载地址 官网地址点击进入 2 配置环境变量 解压到自己想要放置的路径后 配置系统用户的环境变量 新增系统变量 MAVEN HOME C Program Files JetBrains apache maven 3 8
  • 二维码 ThoughtWorks.QRCode 之 index was outside bounds of the array

    最近在使用ThoughtWorks QRCode过程中 单独生成一个二维码没有出现过问题 在重复利用QRCodeEncoder生成二维码的过程中 会出现index was outside bounds of the array错误 经过调试
  • JS 作用域

    var和let的比较 var是老版JavaScript中定义变量的标识符 let是新版JavaScript中定义变量的标识符 let的出现是为了解决var定义变量的一些遗留问题而推出的 在同一个作用域下 var允许重复声明 let不允许重复
  • SpringBoot整合Minio

    1 引入依赖 POM文件如下