华为云OBS文件上传下载工具类

Java-华为云OBS文件上传下载工具类

1.华为云obs文件上传下载

package com.xxx.util;

import cn.hutool.core.io.FileUtil;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.*;
import com.xxx.web.exception.BizErrorException;
import com.xxx.web.exception.enums.BizErrorCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author xxx
 * @createTime 2021/12/6 16:31
 * @description 华为OBS工具类
 */
@Slf4j
@Component
@RefreshScope
public class HuaweiOBSUtil {

    private static String endPoint;
    private static String ak;
    private static String sk;
    private static String bucketName;

    @Value("${obs.endPoint}")
    public void setEndPoint(String endPoint) {
        HuaweiOBSUtil.endPoint = endPoint;
    }

    @Value("${obs.ak}")
    public void setAk(String ak) {
        HuaweiOBSUtil.ak = ak;
    }

    @Value("${obs.sk}")
    public void setSk(String sk) {
        HuaweiOBSUtil.sk = sk;
    }

    @Value("${obs.bucketName}")
    public void setBucketName(String bucketName) {
        HuaweiOBSUtil.bucketName = bucketName;
    }
    /**
     * 上传File类型文件
     *
     * @param file
     * @return
     */
    public static String uploadFile(File file) {
        return getUploadFileUrl(file);
    }

    /**
     * 上传MultipartFile类型文件
     *
     * @param multipartFile
     * @return
     */
    public static String uploadFile(MultipartFile multipartFile) {
        return getUploadFileUrl(com.xxx.util.FileUtil.MultipartFileToFile(multipartFile));
    }

    private static String getUploadFileUrl(File file) {
        if (com.xxx.util.FileUtil.checkFileNotNull(file)) {
            String fileName = FileUtil.getName(file);
            log.info("上传图片:" + fileName);
            /*log.info("ak:" + ak);
            log.info("sk:" + sk);
            log.info("endPoint:" + endPoint);*/
            ObsClient obsClient = new ObsClient(ak, sk, endPoint);
            try {
                //判断桶是否存在,不存在则创建
                if (!obsClient.headBucket(bucketName)) {
                    obsClient.createBucket(bucketName);
                }
                PutObjectRequest request = new PutObjectRequest();
                request.setBucketName(bucketName);
                request.setObjectKey(fileName);
                request.setFile(file);
                request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
                PutObjectResult result = obsClient.putObject(request);
                String url = result.getObjectUrl();
                log.info("图片路径:" + url);
                return url;
            } catch (Exception e) {
                log.error("图片上传错误:{}", e);
                throw new BizErrorException(BizErrorCodeEnum.FILE_UPLOAD_FAILURE);
            }/* finally {
                删除本地临时文件
                HuaweiOBSUtil.deleteTempFile(file);
            }*/
        }
        return null;
    }


    /**
     * 上传图片自定义code
     *
     * @param ak
     * @param sk
     * @param endPoint
     * @param file
     * @return
     */
    public static String uploadFileByCode(String ak, String sk, String endPoint, String bucket, File file) {
        //String pathname = objectName;
        try {
            String fileName = FileUtil.getName(file);
            log.info("上传图片:" + fileName);
            ObsClient obsClient = new ObsClient(ak, sk, endPoint);
            //判断桶是否存在,不存在则创建
            if (!obsClient.headBucket(bucket)) {
                obsClient.createBucket(bucket);
            }
            PutObjectRequest request = new PutObjectRequest();
            request.setBucketName(bucket);
            request.setObjectKey(fileName);
            request.setFile(file);
            request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
            PutObjectResult result = obsClient.putObject(request);
            String url = result.getObjectUrl();
            log.info("文件名称:"+fileName+"图片路径:" + url);
            return url;
        } catch (Exception e) {
            log.error("图片上传错误:{}", e);
        } /*finally {
            HuaweiOBSUtil.deleteTempFile(file);
        }*/
        return null;
    }

    /**
     * 删除本地临时文件
     *
     * @param file
     */
    public static void deleteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }
    /**
     * 根据文件地址获取名称下载File类型的文件
     * @param fileUrl
     * @return
     */
    public static MultipartFile downloadFileByUrl(String fileUrl){
        try {
            String fileName = getFilenameByUrl(fileUrl);
            // 创建ObsClient实例
            ObsClient obsClient = new ObsClient(ak, sk, endPoint);
            ObsObject obsObject = obsClient.getObject(bucketName, fileName);
            InputStream inputStream = obsObject.getObjectContent();
            //转成MultipartFile
            MultipartFile multipartFile = InputStreamConvertMultipartFileUtil.getMultipartFile(inputStream, fileName);
            //File file = com.xxx.util.FileUtil.MultipartFileToFile(multipartFile);
            return multipartFile;

        } catch (ObsException e) {
            log.error("文件下载失败:{}", e.getMessage());
            throw new BizErrorException(BizErrorCodeEnum.GET_FILE_DOWNLOAD_URL_FAIL);
        }
    }

    /**
     * 批量n天删除之前的文件
     *
     * @param ak
     * @param sk
     * @param endPoint
     * @param bucket
     * @param requireHours
     */
    public static void batchDeleteForHoursago(String ak, String sk, String endPoint, String bucket, int requireHours) {
        ObsClient obsClient = new ObsClient(ak, sk, endPoint);
        long currentTime = new Date().getTime();
        try {
            ListObjectsRequest listRequest = new ListObjectsRequest(bucket);
            listRequest.setMaxKeys(1000); // 每次至多返回1000个对象
            ObjectListing listResult;
            Date lastModified;
            long hourMillisecond = 1000 * 3600 * 1;
            // 分页查询
            do {
                List<KeyAndVersion> toDelete = new ArrayList<>();
                listResult = obsClient.listObjects(listRequest);
                for (ObsObject obsObject : listResult.getObjects()) {
                    lastModified = obsObject.getMetadata().getLastModified();
                    long diffs = (currentTime - lastModified.getTime()) / hourMillisecond; // 当前时间减去文件修改时间
                    if (diffs > requireHours
                            && (obsObject.getObjectKey().endsWith(".ts") || obsObject.getObjectKey().endsWith(".mp4"))) {
                        log.info("文件距现在{}小时,对象更改日期:{},文件对象:{}", diffs, lastModified, obsObject.getObjectKey());
                        toDelete.add(new KeyAndVersion(obsObject.getObjectKey()));
                    }
                }
                // 设置下次列举的起始位置
                listRequest.setMarker(listResult.getNextMarker());

                //批量删除文件
                log.info("待删除的OBS对象数量:{}", toDelete.size());
                if (!CollectionUtils.isEmpty(toDelete)) {
                    DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest(bucket);
                    deleteRequest.setQuiet(true); // 设置为quiet模式,只返回删除失败的对象
                    deleteRequest.setKeyAndVersions(toDelete.toArray(new KeyAndVersion[toDelete.size()]));
                    DeleteObjectsResult deleteResult = obsClient.deleteObjects(deleteRequest);
                    if (!CollectionUtils.isEmpty(deleteResult.getErrorResults())) {
                        log.error("删除失败的OBS对象数量:{}", deleteResult.getErrorResults().size());
                    }
                }
            } while (listResult.isTruncated());

        } catch (Exception e) {
            log.error("华为OBS批量删除异常", e);
        } finally {
            try {
                obsClient.close();
            } catch (IOException e) {
                log.error("华为OBS关闭客户端失败", e);
            }
        }
    }

    /**
     * 删除单个对象
     *
     * @param ak
     * @param sk
     * @param endPoint
     * @param bucket
     * @param objectKey
     * @return
     */
    public static boolean deleteFile(String ak, String sk, String endPoint, String bucket, String objectKey) {
        ObsClient obsClient = new ObsClient(ak, sk, endPoint);
        DeleteObjectResult deleteObjectResult = obsClient.deleteObject(bucket, objectKey);
        boolean deleteMarker = deleteObjectResult.isDeleteMarker();
        try {
            obsClient.close();
        } catch (IOException e) {
            log.error("华为OBS关闭客户端失败", e);
        }
        return deleteMarker;
    }

    /**
     * 查询桶内已使用空间大小
     *
     * @param ak
     * @param sk
     * @param endPoint
     * @param bucket
     * @return 单位字节
     */
    public static long getBucketUseSize(String ak, String sk, String endPoint, String bucket) {
        ObsClient obsClient = new ObsClient(ak, sk, endPoint);
        BucketStorageInfo storageInfo = obsClient.getBucketStorageInfo(bucket);
        log.info("{} 桶内对象数:{}  已使用的空间大小B:{} GB:{}", bucket, storageInfo.getObjectNumber(), storageInfo.getSize(), storageInfo.getSize() / 1024 / 1024 / 1024);
        try {
            obsClient.close();
        } catch (IOException e) {
            log.error("华为OBS关闭客户端失败", e);
        }
        return storageInfo.getSize();
    }


    public static String readFileContent(String fileName) {
        File file = new File(fileName);
        BufferedReader reader = null;
        StringBuffer sbf = new StringBuffer();
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempStr;
            while ((tempStr = reader.readLine()) != null) {
                sbf.append(tempStr);
            }
            reader.close();
            return sbf.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return sbf.toString();
    }

    /**
     * 根据下载地址url获取文件名称
     * @param url
     * @throws IOException
     */
    public static String getFilenameByUrl(String url){
        String fileName= null;
        try {
            //url编码处理,中文名称会变成百分号编码
            String decode = URLDecoder.decode(url, "utf-8");
            fileName = decode.substring(decode.lastIndexOf("/")+1);
            log.info("fileName :" + fileName);
        } catch (UnsupportedEncodingException e) {
            log.error("getFilenameByUrl() called with exception => 【url = {}】", url,e);
            e.printStackTrace();
        }
        return fileName;
    }
}

2.文件流转MultipartFile

package com.xxx.util;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 将输入流转成文件
 * @author xiaoxiangyuan
 *
 */
public class InputStreamConvertMultipartFileUtil {

	private static Logger log = LoggerFactory.getLogger(InputStreamConvertMultipartFileUtil.class);

	 /**
     * 获取封装得MultipartFile
     *
     * @param inputStream inputStream
     * @param fileName    fileName
     * @return MultipartFile
     */
    public static MultipartFile getMultipartFile(InputStream inputStream, String fileName) {
        FileItem fileItem = createFileItem(inputStream, fileName);
        //CommonsMultipartFile是feign对multipartFile的封装,但是要FileItem类对象
        return new CommonsMultipartFile(fileItem);
    }


    /**
     * FileItem类对象创建
     *
     * @param inputStream inputStream
     * @param fileName    fileName
     * @return FileItem
     */
    public static FileItem createFileItem(InputStream inputStream, String fileName) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        String textFieldName = "file";
        FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, fileName);
        int bytesRead = 0;
        byte[] buffer = new byte[10 * 1024 * 1024];
        OutputStream os = null;
        //使用输出流输出输入流的字节
        try {
            os = item.getOutputStream();
            while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            inputStream.close();
        } catch (IOException e) {
            log.error("Stream copy exception", e);
            throw new IllegalArgumentException("文件上传失败");
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    log.error("Stream close exception", e);

                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("Stream close exception", e);
                }
            }
        }
        return item;
    }

    public static void main(String[] args) {
  }
}

package com.xxx.util.img;

import org.springframework.web.multipart.MultipartFile;

import java.io.*;

public class ConvertToMultipartFile implements MultipartFile {
    private byte[] fileBytes;
    String name;
    String originalFilename;
    String contentType;
    boolean isEmpty;
    long size;

    public ConvertToMultipartFile(byte[] fileBytes, String name, String originalFilename, String contentType,
                                  long size) {
        this.fileBytes = fileBytes;
        this.name = name;
        this.originalFilename = originalFilename;
        this.contentType = contentType;
        this.size = size;
        this.isEmpty = false;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getOriginalFilename() {
        return originalFilename;
    }

    @Override
    public String getContentType() {
        return contentType;
    }

    @Override
    public boolean isEmpty() {
        return isEmpty;
    }

    @Override
    public long getSize() {
        return size;
    }

    @Override
    public byte[] getBytes() throws IOException {
        return fileBytes;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(fileBytes);
    }

    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        new FileOutputStream(dest).write(fileBytes);
    }
}

3.File转换为MultipartFile

 /**
     * File转换为MultipartFile
     * @param file
     * @return
     */
    public static MultipartFile fileToMultipartFile(File file) {
        FileItem item = new org.apache.commons.fileupload.disk.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);
    }

4.将MultipartFile转换为File

/**
     * 将MultipartFile转换为File
     * @param multiFile
     * @return
     */
    public static File MultipartFileToFile(MultipartFile multiFile) {
        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        // 获取文件后缀
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        // 若须要防止生成的临时文件重复,能够在文件名后添加随机码

        try {
            File file = File.createTempFile(FileUtil.getFileNameNotPrefix(fileName), prefix);
            multiFile.transferTo(file);
            return file;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 /**
     * 获取文件名不带后缀
     *
     * @param fileName
     * @return
     */
    public static String getFileNameNotPrefix(String fileName) {
        String prefix = fileName.substring(fileName.indexOf("."));
        int num = prefix.length();//得到后缀名长度
        String fileOtherName = fileName.substring(0, fileName.length() - num);//得到文件名。去掉了后缀
        return fileOtherName;
    }

5.MultipartFile 获取文件编码为base64

   /**
     * 将MultipartFile 图片文件编码为base64
     * @param file
     * @param status  true加:data:multipart/form-data;base64,前缀   false 不加前缀
     * @return
     */
    public static String generateBase64(MultipartFile file,Boolean status){
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("图片不能为空!");
        }
        String fileName = file.getOriginalFilename();
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        String contentType = file.getContentType();
        byte[] imageBytes = null;
        String base64EncoderImg="";
        try {
            imageBytes = file.getBytes();
            BASE64Encoder base64Encoder =new BASE64Encoder();
            /**
             * 1.Java使用BASE64Encoder 需要添加图片头("data:" + contentType + ";base64,"),
             *   其中contentType是文件的内容格式。
             * 2.Java中在使用BASE64Enconder().encode()会出现字符串换行问题,这是因为RFC 822中规定,
             *   每72个字符中加一个换行符号,这样会造成在使用base64字符串时出现问题,
             *   所以我们在使用时要先用replaceAll("[\\s*\t\n\r]", "")解决换行的问题。
             */
            if (status) {
                base64EncoderImg = "data:" + contentType + ";base64," + base64Encoder.encode(imageBytes);
            }else{
                base64EncoderImg =  base64Encoder.encode(imageBytes);
            }
            base64EncoderImg = base64EncoderImg.replaceAll("[\\s*\t\n\r]", "");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return base64EncoderImg;
    }

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java小白笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值