项目中的ZIP文件解析

上传文件抽象层

public interface IUpload {
    //ftp file input stream
    UploadResultEntity upload(InputStream inputStream, Charset character) throws IOException;
}

上传通用功能

public abstract class AbstractUpload {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    protected PlatformConfig platformConfig;

    @Autowired
    protected RestTemplate restTemplate;

    @Autowired
    protected AddEventData addEventData;


    /**
     * 分析图片是否违法
     * 经过多个模型分型后,得出多种结果列表
     * @param imageUrl
     * @return
     */
    protected JSONObject analyzeImage(String imageUrl) {
        JSONObject whereIn = new JSONObject();
        JSONObject whereOut = new JSONObject();
        String url = platformConfig.getAnalyzeUrlArray()[0];
        whereIn.put("uri", imageUrl);
        whereOut.put("data", whereIn);
        JSONObject bodyData = restTemplate.postForObject(url, whereOut, JSONObject.class);
        Integer code = bodyData.getInteger("code");
        if (code == 0 || code == 200) {
            JSONObject result = bodyData.getJSONObject("result");
            if (result != null) {
                JSONArray detections = result.getJSONArray("detections");
                if (detections.size() == 0) {
                    logger.error("图片({})不能识别", imageUrl);
                    return null;
                }
            }
        }
        logger.info("({})文件的分析结果:{}", imageUrl, bodyData);
        return bodyData;
    }

    /**
     * 根据添加结果判断该zip包是否可以删除
     * @param addResult
     * @return
     */
    protected Boolean checkEnableDel(List<Integer> addResult) {
        Boolean result = false;
        if (addResult.size() == 2) {
            if (addResult.get(0) > 0) {
                if (addResult.get(1) > 0) {
                    result = true;
                }
            }
        }
        return result;
    }

    /**
     * 根据zip中的文件名,获取上传到minio的文件名
     * 返回的文件名字可能包含中文,对应的车牌号的第一个字
     * @param fileFullPath 文件全路径
     * @return
     */
    public String getFileNameFromZipFullPath(String fileFullPath) {
        if (StringUtils.isEmpty(fileFullPath)) {
            return null;
        }
        int i = fileFullPath.lastIndexOf("/");
        String yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        return new StringBuilder(yyyyMMddHHmmss).append("_").append(fileFullPath.substring(i + 2)).toString();
    }


    /**
     * 根据minio的url 获取文件名
     * @param fileUrl
     * @return
     */
    public String getFileNameFromUrl(String fileUrl){
        int i = fileUrl.lastIndexOf("/");
        return fileUrl.substring(i+1);
    }
}

文件保存到本地

@Component
public class UploadLocal extends AbstractUpload implements IUpload {

    @Override
    public UploadResultEntity upload(InputStream inputStream, Charset charset) throws IOException {
        UploadResultEntity uploadResultEntity = new UploadResultEntity();
        @Cleanup ZipInputStream zin = new ZipInputStream(inputStream, charset);
        ZipEntry nextEntry=null;
        while ((nextEntry= zin.getNextEntry())!=null){
            //这里只读取json文件,进行解析
            if (nextEntry.getName().endsWith(platformConfig.getJsonSuffix())) {
                /**
                 * step1.解析对应的json文件
                 */

                @Cleanup ByteArrayOutputStream byteArrayOutputStream  = new ByteArrayOutputStream();
                byte[] bytes = new byte[1024];
                int len = -1;
                while ((len = zin.read(bytes))!=-1){
                    byteArrayOutputStream.write(bytes,0,len);
                }
                String s = new String(byteArrayOutputStream.toByteArray(),"UTF-8");
                JSONObject jsonObject = JSON.parseObject(s, JSONObject.class);
                uploadResultEntity.setJsonFileContent(jsonObject);
                logger.info("({})json文件数据:{}",nextEntry.getName(),jsonObject);

                /**
                 * step2.调用推流接口,分析违法信息
                 */
                String imageUrl = jsonObject.getString("picVehicle");
                JSONObject analyzeResult = analyzeImage(imageUrl);
                uploadResultEntity.setAnalyzeResult(analyzeResult);

                /**
                 * step3.添加违法事件,入库dumper
                 */
                if (analyzeResult == null) {
                    logger.info("图片没有识别结果,直接返回");
                    uploadResultEntity.setEnableDelete(true);
                }else{
                    List<Integer> add = addEventData.add(jsonObject, analyzeResult);
                    logger.info("入库的ID:{}",add);
                    uploadResultEntity.setEnableDelete(checkEnableDel(add));
                }

            }
            zin.closeEntry();
        }

        return uploadResultEntity;
    }
}

文件保存到MINIO


@Component
public class UploadOss extends AbstractUpload implements IUpload{
    private static final String CAR_CODE_SUFFIX = "picPlate.jpg"; //车牌图片后缀
    private static final String ORIGIN_SUFFIX = "picVehicle.jpg"; //原图图片后缀
    private static final String COMPRESS_SUFFIX = "Abbreviate.jpg"; //压缩图片后缀
    @Autowired
    private ImageUploadMinioServiceImpl imageUploadMinioService;

    @Autowired
    private ImageUploadOssServiceImpl imageUploadOssService;

    @Autowired
    private MinIOConfig minIOConfig;

    @Autowired
    private PlatformConfig platformConfig;

    /**
     * oss上传以下步骤:
     * 1.读取一个json 文件
     * 2.将对应三张图片上传至minio 同时记录对应的图片minio 的url地址
     * 3.使用minio 中的图片地址,进行推理算法,获取结果
     * 4.如果算法没有结果,直接跳至 5.,否在进行以下步骤
     *    step1.将对应三张图片的地址上传至oss,同时记录oss 的url 地址
     *    step2.将对应的url更新至json中,落库到dumper
     * 5.根据配置,针对没有识别的图片,是否进行删除处理
     */
    @Override
    public UploadResultEntity upload(InputStream inputStream, Charset charset) throws IOException {
        UploadResultEntity uploadResultEntity = new UploadResultEntity();

        @Cleanup ZipInputStream zin = new ZipInputStream(inputStream, charset);
        ZipEntry nextEntry;

        while ((nextEntry= zin.getNextEntry())!=null){

            String nextEntryFullPath = nextEntry.getName(); //当前文件的全路径
            /**
             * 1.读取一个json 文件
             */
            if (nextEntry.getName().endsWith(platformConfig.getJsonSuffix())) {
                @Cleanup ByteArrayOutputStream byteArrayOutputStream  = new ByteArrayOutputStream();
                byte[] bytes = new byte[1024];
                int len = -1;
                while ((len = zin.read(bytes))!=-1){
                    byteArrayOutputStream.write(bytes,0,len);
                }
                String s = new String(byteArrayOutputStream.toByteArray(),"UTF-8");
                JSONObject jsonObject = JSON.parseObject(s, JSONObject.class);
                uploadResultEntity.setJsonFileContent(jsonObject);
                logger.info("({})json文件数据:{}",nextEntry.getName(),jsonObject);
            }

            /**
             * 2.将对应三张图片上传至minio 同时记录对应的图片minio 的url地址
             */
            if (fileFilterEndWith(nextEntryFullPath)) {
                @Cleanup ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                byte[] bytes = new byte[1024];
                int len = -1;
                while ((len = zin.read(bytes)) != -1) {
                    byteArrayOutputStream.write(bytes, 0, len);
                }
                String fileNameFromZipFullPath = getFileNameFromZipFullPath(nextEntry.getName());
                @Cleanup ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                String imageUrl = imageUploadMinioService.upload(byteArrayInputStream, fileNameFromZipFullPath);
                logger.info(" 文件minio 地址 :{}",imageUrl);
                //车牌号图片url
                if (nextEntryFullPath.endsWith(CAR_CODE_SUFFIX)) {
                    uploadResultEntity.setMinioPicPlate(imageUrl);
                }
                //原图url
                else if (nextEntryFullPath.endsWith(ORIGIN_SUFFIX)) {
                    uploadResultEntity.setMinioPicVehicle(imageUrl);
                    String fileName = getFileNameFromUrl(imageUrl);
                    uploadResultEntity.setFileKey(minIOConfig.DEFAULT_BUCKETNAME.concat("/").concat(fileName));
                }
                //压缩图url
                else if (nextEntryFullPath.endsWith(COMPRESS_SUFFIX)) {
                    uploadResultEntity.setMinioPicAbbreviate(imageUrl);
                }
            }

            zin.closeEntry();
        }


        /**
         * 3.使用minio 中的图片地址,进行推理算法,获取结果
         */
        if (uploadResultEntity.getMinioPicVehicle() != null) {
            JSONObject jsonObject = analyzeImage(uploadResultEntity.getMinioPicVehicle());
            uploadResultEntity.setAnalyzeResult(jsonObject);
        }

        /**
         * 4.根据推理结果,进行以下操作
         */
        if (uploadResultEntity.getAnalyzeResult() != null) {
            //step1.将对应三张图片的地址上传至oss,同时记录oss 的url 地址

            //车牌号
            String ossPicPlateUrl = imageUploadOssService.upload(uploadResultEntity.getMinioPicPlate(),
                    getFileNameFromUrl(uploadResultEntity.getMinioPicPlate()));
            uploadResultEntity.setOssPicPlate(ossPicPlateUrl);
            //原图
            String ossPicVehicleUrl = imageUploadOssService.upload(uploadResultEntity.getMinioPicVehicle(),
                    getFileNameFromUrl(uploadResultEntity.getMinioPicVehicle()));
            uploadResultEntity.setOssPicVehicle(ossPicVehicleUrl);
            //压缩图
            String ossPicAbbreviateUrl = imageUploadOssService.upload(uploadResultEntity.getMinioPicAbbreviate(),
                    getFileNameFromUrl(uploadResultEntity.getMinioPicAbbreviate()));
            uploadResultEntity.setOssPicAbbreviate(ossPicAbbreviateUrl);


            //step2.将对应的url更新至json中,落库到dumper
            uploadResultEntity.getJsonFileContent().put("picPlate", uploadResultEntity.getOssPicPlate());
            uploadResultEntity.getJsonFileContent().put("picVehicle", uploadResultEntity.getOssPicVehicle());
            uploadResultEntity.getJsonFileContent().put("picAbbreviate", uploadResultEntity.getOssPicAbbreviate());
            uploadResultEntity.getJsonFileContent().put("fileKey",uploadResultEntity.getFileKey());
            uploadResultEntity.getJsonFileContent().put("picVehicleMinioUrl",uploadResultEntity.getMinioPicVehicle());

            List<Integer> add = addEventData.add(uploadResultEntity.getJsonFileContent(), uploadResultEntity.getAnalyzeResult());
            uploadResultEntity.setEnableDelete(checkEnableDel(add));
            logger.info("入库的ID:{} ,是否可删除({})", add, uploadResultEntity.getEnableDelete());
        }else{
            uploadResultEntity.setEnableDelete(true);
        }

        /**
         * 5.根据配置,针对没有识别的图片,删除minio文件
         *  step1.删除没有识别的图片
         *  step2.删除oss中除原图外的两张图片
         */
        if (uploadResultEntity.getMinioPicPlate() != null) {
            imageUploadMinioService.delete(uploadResultEntity.getMinioPicPlate());
        }
        if (uploadResultEntity.getMinioPicAbbreviate() != null) {
            imageUploadMinioService.delete(uploadResultEntity.getMinioPicAbbreviate());
        }
        if (uploadResultEntity.getAnalyzeResult() == null) {
            if (platformConfig.getIsDelUnableMinioFile()) {
                if (uploadResultEntity.getMinioPicVehicle() != null) {
                    imageUploadMinioService.delete(uploadResultEntity.getMinioPicVehicle());
                }
            }
        }

        return uploadResultEntity;
    }



    /**
     * 文件是否属于读取范畴
     * @param fileName
     * @return
     */
    private boolean fileFilterEndWith(String fileName) {
        logger.info("zip file name : {}",fileName);
        boolean ok = false;
        return ok || fileName.endsWith(CAR_CODE_SUFFIX)
                || fileName.endsWith(ORIGIN_SUFFIX)
                || fileName.endsWith(COMPRESS_SUFFIX);
    }


    /**
     * 根据分析结果,将图片下载到不同的位置
     * @param fileUrl
     * @param analyzeResult
     * @throws IOException
     */
    private void download(String fileUrl, JSONObject analyzeResult) throws IOException {
        int i = fileUrl.lastIndexOf("/");
        String fileName = fileUrl.substring(i+1);
        //有分析结果,则保存到一个文件夹
        if (analyzeResult != null) {
            String filePath = new StringBuilder(platformConfig.getEnableFileLocalPath()).append("/").append(fileName).toString();
            File file = new File(filePath);
            @Cleanup FileOutputStream fileOutputStream = new FileOutputStream(file);
            URL url = new URL(fileUrl);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.connect();
            @Cleanup InputStream inputStream = httpURLConnection.getInputStream();
            int copy = IOUtils.copy(inputStream, fileOutputStream);
            httpURLConnection.disconnect();
            logger.info("不可识别图片保存({})", copy);
        } else {
            String filePath = new StringBuilder(platformConfig.getUnableFileLocalPath()).append("/").append(fileName).toString();
            File file = new File(filePath);
            @Cleanup FileOutputStream fileOutputStream = new FileOutputStream(file);
            URL url = new URL(fileUrl);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.connect();
            @Cleanup InputStream inputStream = httpURLConnection.getInputStream();
            int copy = IOUtils.copy(inputStream, fileOutputStream);
            httpURLConnection.disconnect();
            logger.info("可识别图片保存({})", copy);
        }
    }
}

posted @   Eular  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示