windows,liunx,java实现apk解压,去签名、重新签名,重新打包apk

28 篇文章 1 订阅
14 篇文章 0 订阅

背景:由于项目需要,需要将apk包加入服务端返回的静态资源文件到apk中,形成离线apk包供下载安装。经过调查研究,决定使用apktool实现。关于apktool的资料可以参考

https://blog.csdn.net/quantum7/article/details/124060620

https://blog.csdn.net/qq_20451879/article/details/117300056

windows版环境

1.JDK环境

2.下载apktool.jar

打包流程:

apktool下载地址:https://ibotpeaches.github.io/Apktool/
3.解压apk包
java -jar apktool_2.6.1.jar d app-release.apk
4删除签名文件
签名文件在解压文件后的\original\META-INF目录下
C:\Users***\Downloads\app-release1111\original\META-INF

5.添加要替换的文件到
C:\Users***\Downloads\app-release\assets\assets下

6.生成签名文件

.keystore 签名方式:

keytool -genkey -alias test.keystore -keyalg RSA -validity 20000 -keystore test.keystore

.jks方式:

keytool -genkey -v -keystore test.jks -alias test-keyalg RSA -keysize 2048 -validity 20000

keytool -importkeystore -srckeystore test.jks -destkeystore test.jks -deststoretype pkcs12

7.重新打包
java -jar apktool_2.6.1.jar b app-release

8.使用重新打包后的apk和签名文件打包

.keystore重新签名打包方式:

jarsigner -verbose -keystore test.keystore -signedjar app-release-1-0224.apk app-release-1.apk test.keystore

.jks重新签名打包方式:

jarsigner -verbose -keystore test.jks -signedjar 222.apk test.apk test

liunx环境安装apktool

可参考下面网站

https://ibotpeaches.github.io/Apktool/install/

java环境

构建脚本

bulidApk.bat

@echo off
start cmd /k "cd C:\Users\aipingh\Downloads && java -jar C:\Users\aipingh\Downloads\apktool.jar b C:\Users\***\Downloads\app-release8"

rebuildKeystoreApk.bat

@echo off
start cmd /k "cd C:\Users\aipingh\Downloads && jarsigner -verbose -keystore tinnove.keystore -storepass 123456 -signedjar C:\Users\***\Downloads\app-release8\dist\app-release.apk C:\Users\aipingh\Downloads\app-release8\dist\app-release8.apk test.keystore"

代码:



import ch.qos.logback.core.util.FileUtil;
import cn.hutool.core.io.FileUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class ApkUtil {

    private String outPth;

    // windows版下载
    public void downloadWindowsOfflineApk(InfoReqVO reqVO, HttpServletResponse response) {
        try {
            //  apk解压包路径
            String apkOriginalPath = "C:\\Users\\***\\Downloads\\app-release8\\";
            // 下载离线js文件到目标apk的资源文件路径中
            String fullPath = apkOriginalPath + "original\\META-INF\\";
            downloadJsFile(reqVO);
            //删除签名文件
            File mkdir = FileUtil.mkdir(fullPath);
            //去掉签名
            FileUtils.deleteTempFiles(mkdir, fullPath);
            //重新打包
            try {
                String commandStr = "cmd /c C:\\Users\\***\\Downloads\\buildApk.bat";
                Runtime.getRuntime().exec(commandStr);
            } catch (IOException e) {

            }
            // 下载签名文件到dist目录中
            String packagePath = "dist";
            File packagePathFile = FileUtil.mkdir(apkOriginalPath + packagePath);
            String keystorePath = "https://***/apk/keystore/tinnove.keystore";
            ImageInfo appDesignDetailImageInfo = new ImageInfo();
            appDesignDetailImageInfo.setFilename("tinnove.keystore");
            appDesignDetailImageInfo.setPathUrl(keystorePath);
            downloadFile(packagePathFile, appDesignDetailImageInfo);
            // 加签名后打包APK
            try {
                String commandStr = "cmd /c C:\\Users\\***\\Downloads\\rebuildKeystoreApk.bat";
                Runtime.getRuntime().exec(commandStr).waitFor(30, TimeUnit.MILLISECONDS);
            } catch (IOException e) {
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 重新构建后的apk文件地址
            String newApkName = "app-release.apk";
            String newApkPath = apkOriginalPath + "dist\\" + newApkName;
            // 将apk包返回给前端
            File file = new File(newApkPath);
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("app-release.apk", "UTF-8"));
            //获取文件的输入流
            InputStream fis = new FileInputStream(file);
            byte[] buffer = new byte[1024 * 5];
            int r;
            while ((r = fis.read(buffer)) != -1) {
                response.getOutputStream().write(buffer, 0, r);
            }
            // 删除build目录,方便下次打包
            FileUtils.deleteTempFiles(null, apkOriginalPath + "build");
            // 删除dist及目录下的apk包
            FileUtils.deleteTempFiles(null, apkOriginalPath + "dist");
        } catch (IOException e) {
        }
    }

    //liunx版下载
    public void apkShellDownload(InfoReqVO reqVO, HttpServletResponse response) {
     InputStream fis = null;
        try {
            String apkOriginalPath = apkPath;
            String apkDistPath = apkPath + "dist/";
            String newApkName = "app-release-" + reqVO.getDesignId() + "-" + reqVO.getCount() + ".apk";
            FileUtils.execSh("java -jar  " + designOfflinePath + "apktool.jar  d  " + designOfflinePath + "app-release.apk");
            // 下载离线js文件到目标apk的资源文件路径中
            String fullPath = apkOriginalPath + "original/META-INF/";
            downloadJsFile(reqVO);
            //删除签名文件 去掉签名
            FileUtil.clean(fullPath);
            FileUtil.del(fullPath);
            FileUtils.execSh(" java -jar  " + designOfflinePath + "apktool.jar b  " + apkOriginalPath
                    + " && " + "cp " + designOfflinePath + "test.keystore  " + apkDistPath + " && "
                    + "cp " + designOfflinePath + "test.keystore  " + apkDistPath + " && "
                    + "cd  app-release/dist/" + " && "
                    + "jarsigner -verbose -keystore test.keystore -storepass *****-signedjar  " + newApkName + "  app-release.apk tinnove.keystore", 10, TimeUnit.SECONDS);
            // 将签名文件移动到到dist目录中
            log.info("将签名文件移动到到dist目录中===");
            try {
                log.info("thread start sleep={} ==== ", System.currentTimeMillis());
                // 抛出异常后,同时清除中断信号
                Thread.sleep(15 * 1000);
                // 将apk包返回给前端
                File parentFile = new File(apkDistPath);
                if (!parentFile.exists()) {
                    parentFile.mkdirs();
                }
                File file = FileUtil.file(parentFile, newApkName);
                log.info("apk file ={}", file.exists());
                if (file.exists()) {
                    response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + newApkName);
                    //获取文件的输入流
                    fis = new FileInputStream(file);
                    byte[] buffer = new byte[1024 * 5];
                    int r;
                    while ((r = fis.read(buffer)) != -1) {
                        response.getOutputStream().write(buffer, 0, r);
                    }
                }
                // 删除临时目录
                FileUtil.clean(apkOriginalPath);
            } catch (InterruptedException e) {
                log.error("重新设置线程中断状态失败,原因是e={}", e.getMessage());
                //重新设置线程中断状态为true
                Thread.currentThread().interrupt();
            }
        } catch (IOException e) {
            log.error("执行打包命令失败e={}", e.getMessage());
        } finally {
            if (null != fis) {
                try {
                    fis.close();
                } catch (IOException e) {
                    log.error("fis close 失败e={}", e.getMessage());
                }
            }
        }
    }

    private void downloadFile(File target, ImageInfo detailImageInfo) throws IOException {
        File file = org.apache.commons.io.FileUtils.getFile(target, detailImageInfo.getFilename());
        FileOutputStream outputStream = new FileOutputStream(file);
        //获取文件的网络输入流
        byte[] bytes = cn.hutool.http.HttpUtil.downloadBytes(detailImageInfo.getPathUrl());
        InputStream fis = new ByteArrayInputStream(bytes);
        byte[] buffer = new byte[1024 * 5];
        int r;
        while ((r = fis.read(buffer)) != -1) {
            outputStream.write(buffer, 0, r);
        }
        fis.close();
        outputStream.close();
    }

    private void downloadJsFile(InfoReqVO reqVO) {
        try {
            //apk包所在的服务器路径
            String fullPath = outPth + "/app-release/" + "/assets/app-data/";
            //本地路径
//            String fullPath = "C:\\Users\\xxx\\Downloads\\app-release\\assets\\app-data";
//        String fullPath = designOfflinePath + "/" + reqVO.getDesignId() + "/" + reqVO.getCount() + "/";
            File target = cn.hutool.core.io.FileUtil.mkdir(new File(fullPath));
//            File target = new File(fullPath + "preview");
//
//            // 返回图片文件夹
            List<ImageInfo> designDetailImages = new ArrayList<>();
            downloadFiles(designDetailImages, target);
            // 返回逻辑连线 json文件
            List<Object> designLogicWiring = new ArrayList<>();
            String logicWiringListJs = "let  logicWiringList  = " + cn.hutool.json.JSONUtil.toJsonStr(designLogicWiring);
            FileUtils.object2JsonFile(fullPath + "logicWiring.js", logicWiringListJs);
            // 返回图片url json文件
//            List<AppDesignDetailImageInfo> designDetailImageUrls = getImagesInfo(reqVO);
//            String previewJs = "let  previewImageUrls = " + JSONUtil.toJsonStr(designDetailImageUrls);
//            FileUtils.object2JsonFile(fullPath + "preview.js", previewJs);
            // 返回分组 json文件
            List<Object> groupList = new ArrayList<>();
            String groupListJs = "let  groupList = " + cn.hutool.json.JSONUtil.toJsonStr(groupList);
            FileUtils.object2JsonFile(fullPath + "group.js", groupListJs);
        } catch (Exception e) {
        }
    }

    private void downloadFiles(List<ImageInfo> designDetailImages, File target) {
        try {
            //将输出流转换成Zip输出流
            for (ImageInfo detailImageInfo : designDetailImages) {
                downloadFile(target, detailImageInfo);
            }
        } catch (IOException e) {
        }
    }

}


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
import java.util.concurrent.TimeUnit;

/**
 * 文件处理工具类
 *
 * @author
 */
@Slf4j
public class FileUtils {
    /**
     * 字符常量:斜杠 {@code '/'}
     */
    public static final char SLASH = '/';

    /**
     * 字符常量:反斜杠 {@code '\\'}
     */
    public static final char BACKSLASH = '\\';

    public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";

    /**
     * 输出指定文件的byte数组
     *
     * @param filePath 文件路径
     * @param os       输出流
     * @return
     */
    public static void writeBytes(String filePath, OutputStream os) throws IOException {
        FileInputStream fis = null;
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                throw new FileNotFoundException(filePath);
            }
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int length;
            while ((length = fis.read(b)) > 0) {
                os.write(b, 0, length);
            }
        } catch (IOException e) {
            throw e;
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    /**
     * 删除文件
     *
     * @param filePath 文件
     * @return
     */
    public static boolean deleteFile(String filePath) {
        boolean flag = false;
        File file = new File(filePath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 文件名称验证
     *
     * @param filename 文件名称
     * @return true 正常 false 非法
     */
    public static boolean isValidFilename(String filename) {
        return filename.matches(FILENAME_PATTERN);
    }

    /**
     * 检查文件是否可下载
     *
     * @param resource 需要下载的文件
     * @return true 正常 false 非法
     */
    public static boolean checkAllowDownload(String resource) {
        // 禁止目录上跳级别
        if (StringUtils.contains(resource, "..")) {
            return false;
        }

        // 检查允许下载的文件规则
        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))) {
            return true;
        }

        // 不在允许下载的文件规则
        return false;
    }

    /**
     * 下载文件名重新编码
     *
     * @param request  请求对象
     * @param fileName 文件名
     * @return 编码后的文件名
     */
    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException {
        final String agent = request.getHeader("USER-AGENT");
        String filename = fileName;
        if (agent.contains("MSIE")) {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            filename = new String(fileName.getBytes(), "ISO8859-1");
        } else if (agent.contains("Chrome")) {
            // google浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        } else {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }

    /**
     * 返回文件名
     *
     * @param filePath 文件
     * @return 文件名
     */
    public static String getName(String filePath) {
        if (null == filePath) {
            return null;
        }
        int len = filePath.length();
        if (0 == len) {
            return filePath;
        }
        if (isFileSeparator(filePath.charAt(len - 1))) {
            // 以分隔符结尾的去掉结尾分隔符
            len--;
        }

        int begin = 0;
        char c;
        for (int i = len - 1; i > -1; i--) {
            c = filePath.charAt(i);
            if (isFileSeparator(c)) {
                // 查找最后一个路径分隔符(/或者\)
                begin = i + 1;
                break;
            }
        }

        return filePath.substring(begin, len);
    }

    /**
     * 获取文件名,不带后缀
     *
     * @param filePath
     * @return
     */
    public static String getFilename(String filePath) {
        String name = getName(filePath);
        if (null == name) {
            return null;
        }
        if (name.contains(".")) {
            int end = name.indexOf(".");
            return name.substring(0, end);
        }
        return name;
    }

    /**
     * 获取文件后缀 如:.zip
     *
     * @param filePath
     * @return
     */
    public static String getFilenameSuffix(String filePath) {
        String name = getName(filePath);
        if (null == name) {
            return null;
        }
        if (name.contains(".")) {
            int end = name.indexOf(".");
            return name.substring(end);
        }
        return name;
    }

    /**
     * 是否为Windows或者Linux(Unix)文件分隔符<br>
     * Windows平台下分隔符为\,Linux(Unix)为/
     *
     * @param c 字符
     * @return 是否为Windows或者Linux(Unix)文件分隔符
     */
    public static boolean isFileSeparator(char c) {
        return SLASH == c || BACKSLASH == c;
    }

    /**
     * 下载文件名重新编码
     *
     * @param response     响应对象
     * @param realFileName 真实文件名
     * @return
     */
    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException {
        String percentEncodedFileName = percentEncode(realFileName);

        StringBuilder contentDispositionValue = new StringBuilder();
        contentDispositionValue.append("attachment; filename=")
                .append(percentEncodedFileName)
                .append(";")
                .append("filename*=")
                .append("utf-8''")
                .append(percentEncodedFileName);

        response.setHeader("Content-disposition", contentDispositionValue.toString());
        response.setHeader("download-filename", percentEncodedFileName);
    }

    /**
     * 百分号编码工具方法
     *
     * @param s 需要百分号编码的字符串
     * @return 百分号编码后的字符串
     */
    public static String percentEncode(String s) throws UnsupportedEncodingException {
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
        return encode.replaceAll("\\+", "%20");
    }

    /**
     * 获取路径下所有文件名和文件路径
     * 以,分割
     *
     * @param dirPath 目录路径
     * @return hashMap name和url
     */
    public static HashMap<String, String> getMapPath(String dirPath) {
        HashMap<String, String> pathMap = new HashMap<String, String>();
        File dirFile = new File(dirPath);
        String[] fileName = dirFile.list();

        StringJoiner joiner = new StringJoiner(",");
        for (String name : fileName) {
            joiner.add(dirPath + name);
        }

        pathMap.put("name", String.join(",", fileName));
        pathMap.put("url", joiner.toString());
        return pathMap;
    }


    public static boolean deleteAllFile(String dir) {
        File dirFile = new File(dir);
        // 如果dir对应的文件不存在,或者不是一个目录,则退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            return false;
        }
        boolean flag = true;
        // 删除文件夹中的所有文件包括子文件夹
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = deleteFileFlag(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
            // 删除子文件夹
            else if (files[i].isDirectory()) {
                flag = deleteAllFile(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }
        if (!flag) {
            return false;
        }
        // 删除当前文件夹
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 删除文件返回bool
     *
     * @param fileName
     * @return boolean
     */
    public static boolean deleteFileFlag(String fileName) {
        File file = new File(fileName);
        // 如果文件路径只有单个文件
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * json文件转json对象
     *
     * @param data 文件流
     * @return json对象
     */
    public static Map readJsonFile(byte[] data) {
        Gson gson = new Gson();
        String json = "";
        try {
            Reader reader = new InputStreamReader(new ByteArrayInputStream(data), StandardCharsets.UTF_8);
            int ch = 0;
            StringBuilder buffer = new StringBuilder(1024);
            while ((ch = reader.read()) != -1) {
                buffer.append((char) ch);
            }
            reader.close();
            json = buffer.toString();
            return gson.fromJson(json, Map.class);
        } catch (IOException e) {
            log.error("json文件转json对象失败,原因是e={}", e.getMessage());
            return Collections.emptyMap();
        }
    }

    /**
     * Object 转换为 json 文件
     *
     * @param finalPath finalPath 是绝对路径 + 文件名,请确保欲生成的文件所在目录已创建好
     * @param content   需要被转换的 content
     */
    public static void object2JsonFile(String finalPath, String content) {
        try {
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(finalPath), StandardCharsets.UTF_8);
            osw.write(content);
            osw.flush();
            osw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 将java对象转成json文件返回给前端
     *
     * @param object   转换为 json
     * @param fileName json文件名称
     * @param response 结果
     */
    public static void object2JsonFile(Object object, String fileName, HttpServletResponse response) {
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            //获取文件的网络输入流
            byte[] bytes = JSONUtil.toJsonStr(object).getBytes(StandardCharsets.UTF_8);
            InputStream fis = new ByteArrayInputStream(bytes);
            byte[] buffer = new byte[1024 * 5];
            int r;
            while ((r = fis.read(buffer)) != -1) {
                response.getOutputStream().write(buffer, 0, r);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取封装得MultipartFile
     *
     * @param inputStream inputStream
     * @param fileName    fileName
     * @return MultipartFile
     */
    private 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 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[8192];
        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 int execSh(String bashCommand) {
        log.info("开始执行shell命令bashCommand={}", bashCommand);
        int status = 0;
        try {
            Runtime runtime = Runtime.getRuntime();
            String[] bash = {"/bin/bash", "-c", bashCommand};
            Process exec = runtime.exec(bash);
            status = exec.waitFor();
            if (status != 0) {
                return 1;
            }
        } catch (IOException | InterruptedException e) {
            log.error("执行shell命令bashCommand={}失败,原因是e={}", bashCommand, e.getMessage());
        }
        return status;
    }

    /**
     * 执行Shell脚本 0成功 1失败
     */
    public static boolean execSh(String bashCommand, long time, TimeUnit timeUnit) {
        try {
            log.info("开始执行shell命令bashCommand={}", bashCommand);
            Runtime runtime = Runtime.getRuntime();
            String[] bash = {"/bin/bash", "-c", bashCommand};
            Process exec = runtime.exec(bash);
            return exec.waitFor(time, timeUnit);
        } catch (IOException | InterruptedException e) {
            log.error("执行shell命令bashCommand={}失败,原因是e={}", bashCommand, e.getMessage());
        }
        return false;
    }

    public static void deleteTempFiles(File file2, String descDir) {
        File file1 = new File(descDir);
        //删除zip解压的数据
        if (ObjectUtil.isNotEmpty(file1) && file1.exists()) {
            log.info("file1={}", file1.getPath());
            deleteFile(file1);
        }
        //删除zip文件
        //删除zip文件
        if (ObjectUtil.isNotEmpty(file2) && file2.exists()) {
            log.info("file2={}", file2.getPath());
            deleteFile(file2);
        }
    }

    public static void deleteFile(File file) {
        if (file == null) {
            log.info("deleteFile结果file=null");
            return;
        }
        if (file.isFile()) {
            boolean delete = file.delete();
            log.info("删除结果file={},result={}", file.getPath(), delete);
        } else if (file.isDirectory()) {
            for (File sub : file.listFiles()) {
                deleteFile(sub);
            }
            file.delete();
        }
    }

    /**
     * 根据byte数组,生成文件
     *
     * @param bfile    文件数组
     * @param filePath 文件存放路径
     * @param fileName 文件名称
     */
    public static File byte2File(byte[] bfile, String filePath, String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if (!dir.exists() && !dir.isDirectory()) {//判断文件目录是否存在
                dir.mkdirs();
            }
            file = new File(filePath + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bfile);
        } catch (Exception e) {
            log.error("byte数组,生成文件失败,原因是e={}", e.getMessage());
        } finally {
            try {
                if (bos != null) {
                    bos.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (Exception e) {
                log.error(">>>>   byte2File  error" + e.getMessage());
                e.printStackTrace();
            }
        }
        return file;
    }

    public static byte[] base64StrToBytes(String base64Str) {
        byte[] bts = org.apache.tomcat.util.codec.binary.Base64.decodeBase64(base64Str);
        for (int k = 0; k < bts.length; ++k) {
            //调整异常数据
            if (bts[k] < 0) {
                bts[k] += 256;
            }
        }
        return bts;
    }


}



import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @Author:
 * @Description: 校验分享链接入参
 */

@Data
@ApiModel("入参")
public class ImageInfo {

    @ApiModelProperty(name = "id", value = "id", required = true)
    private String id;

    @ApiModelProperty(value = "资源路径")
    private String pathUrl;

    @ApiModelProperty(value = "文件名称")
    private String filename;

}



import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * 入参
 *
 * @author ***
 * @since 2023/02/16
 */

@Data
@ApiModel(入参")
public class InfoReqVO {

    @ApiModelProperty(value = "id")
    private Long id;

    @ApiModelProperty(value = "版本号")
    private Integer version;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值