zip文件操作导致服务崩溃

需求:

zip包中有个json文件,需要将json文件进行转化再生成一个json文件并放到同级目录下。

实现过程

1、未进行解压zip文件,通过zipProp.entries()读取zip包中的文件元素,读取到json文件就进行转化再次生成一个json文件,然后将生成的json文件直接append到原zip文件中(存在于zip包的根目录下),这样的操作不需要对zip包进行解压再压缩,处理速度快,但是生成的json文件和之前的json文件不在同一个目录下。
2、若需要将json文件放置到固定的文件夹中,就必须进行解压,因为.zip文件是一个可执行文件并不属于一个文件夹,无法操作zip包内部属性。
3、zip包进行解压,将生成的json文件copy放置固定目录后再压缩。执行

出现的问题

执行导致服务重启
这了这么长时间的代码,除了内存溢出导致崩溃,第一次出现执行到某行代码直接崩溃,内存,cpu都正常。
附图:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

排查过程

  1. 解压文件正确
  2. json文件copy正确
  3. 压缩包正确
  4. 以上都符合预期,说明业务流程跑完,进入下一次循环
  5. 由于上传解压压缩都使用同一文件名,再次生成的zip包会将原文件覆盖,entries.nextElement()下一项元素调用native方法,涉及底层native方法进入本地C库。
  6. 猜想:由于原文件被替换,原文件找不到,file链接引用的文件不是原文件,或者file链接已断开

疑问:

文件被替换,找原文件下一项元素,利用操作系统的IO操作,调用了C库,为什么会使服务进程重启呢。

附实现过程

public Map<String, Object> uploadFile(CommonsMultipartFile mFile, HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>();
        int state = 1000;
        try {
            if(mFile == null){
                log.warn("ClipUploadServiceImpl mFile 空");
                return null;
            }
            if(mFile.getSize() == 0){
                log.warn("ClipUploadServiceImpl mFile 文件内容空,请重新选择文件");
                return null;
            }
            String prefixStr = "file.51vv.com";
            String suffix = "";   //文件后缀
            String route = "/fileUpload/";
            String saveDir = "/upload" + route;  //定义文件存放地址
            String filename = mFile.getOriginalFilename();   //获得原始文件名
//            String fileNameMD5 = MD5Util.getEncoderByMd5(filename);
//            log.info("FileName的值:[{}],文件名的md5值:[{}]", filename, fileNameMD5);
            log.info("FileName的值:[{}]", filename);
            long fileSize = mFile.getSize();
            if (fileSize > 20000 * 1024) {
                log.warn("[{}]文件太大",filename);
                map.put("msg", filename+"上传文件尺寸超过了限定大小");
                map.put("state", 2000);
                return map;
            }
            if (filename.indexOf(".") != -1) {
                suffix = filename.substring(filename.lastIndexOf("."));
            }
            suffix = suffix.toLowerCase();
            String saveFilePath = saveDir + filename;
            File dir = new File(request.getSession().getServletContext().getRealPath(saveDir)); //文件夹
            // 判断文件夹不存在就创建
            if (!dir.exists()) {
                dir.mkdirs();
                log.info("创建目录:[{}]", dir.getName());
            }
            File file = new File(request.getSession().getServletContext().getRealPath(saveFilePath));
            mFile.getFileItem().write(file);
            String fileMD5 = MD5FileUtility.getFileMD5String(file);
            String saveFile = route + fileMD5 + suffix;   //远程服务器相对url

            String url = prefixStr + saveFile;
            if (".zip".equals(suffix)) {
                ZipFile zipProp = new ZipFile(file, Charset.forName("GBK"));
                for (Enumeration entries = zipProp.entries(); entries.hasMoreElements(); ) {
                    ZipEntry entry = (ZipEntry) entries.nextElement(); //导致问题所在
                    String zipEntryName = entry.getName();
                    if (zipEntryName.endsWith(".json")) {
                        String jsonSuffix = zipEntryName.substring(zipEntryName.lastIndexOf("."));
                        String uuid = zipEntryName.substring(zipEntryName.lastIndexOf("/") + 1, zipEntryName.lastIndexOf("."));
                        String zipdir = zipEntryName.substring(0, zipEntryName.lastIndexOf("/"));
                        log.info("zipEntryName:【{}】,uuid:【{}】,jsonSuffix:【{}】,zipdir:【{}】", zipEntryName, uuid, jsonSuffix, zipdir);
                        InputStream input = zipProp.getInputStream(entry);
                        final int bufferSize = 1024;
                        final char[] buffer = new char[bufferSize];
                        final StringBuilder out = new StringBuilder();
                        Reader in = new InputStreamReader(input, "UTF-8");
                        for (; ; ) {
                            int rsz = in.read(buffer, 0, buffer.length);
                            if (rsz < 0)
                                break;
                            out.append(buffer, 0, rsz);
                        }
                        input.close();
                        String iosJson = out.toString().trim();
                        TemplateJsonConverter templateJsonConverter = new TemplateJsonConverter();
                        String androidJson = templateJsonConverter.transformeParse(uuid, iosJson);
                        String transSaveFilePath = saveDir + uuid + "_android" + jsonSuffix;
                        log.info("生成安卓json文件名:{}", transSaveFilePath);
                        File transFile = new File(request.getSession().getServletContext().getRealPath(transSaveFilePath));
                        FileWriter fileWriter = new FileWriter(transFile);
                        fileWriter.write(androidJson);
                        File unzip = ZipUtil.unzip(file);
                        log.info(unzip.getPath() + "/" + zipdir);
                        FileUtil.copy(transFile,new File(unzip.getPath() + "/" + zipdir), false);
                        ZipUtil.zip(unzip);
                        log.info("压缩完成");
 //                        transFile.delete();   //需要删除安卓的json
//                        unzip.delete();  //删除解压的文件
                        /**
                         * 问题出现的关键处,将文件覆盖后退出for循环
                         */
                        break;    
                    }
                }

            }
            String ret = VdfsUploadUtility.uploadFile(request.getSession().getServletContext().getRealPath(saveFilePath), saveFile);
            }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值