2021-09-19

本文介绍了解压RAR文件的Java实现方法,并解决了实际应用中遇到的问题。此外,还详细介绍了如何对复杂的对象参数进行校验,包括一对一和一对多的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1上传rar的问题

前几天客户提出一个傻逼的需求 上传rar进行解压,这个需求,难点就是在rar的解压的上,一般都是上传zip
难倒我了吗? 不可能的

我就去百度,百度,好多都是有问题,找到一个要钱, 但是可以用 这里就分享给大家

public class RARUtil {
    public static void main(String[] args) {
        File file = new File("C:\\Users\\lenovo\\Desktop\\图片");
        File[] tempList = file.listFiles();

        for (int i = 0; i < tempList.length; i++) {
            if (tempList[i].isFile()) {
                //这里不进行递归
                System.out.println(   tempList[i].getPath());
                System.out.println(tempList[i].getName());


                //文件名,不包含路径
                //String fileName = tempList[i].getName();
            }

        }
    }
    public static void decompressFile(String inputFilePath,final String targetFileDir) {
        //解压7zip文件
        RandomAccessFile randomAccessFile = null;
        IInArchive inArchive = null;
        try {
            // 判断目标目录是否存在,不存在则创建
            File newdir = new File(targetFileDir);
            if (false == newdir.exists()) {
                newdir.mkdirs();
                newdir = null;
            }
            randomAccessFile = new RandomAccessFile(inputFilePath, "r");
            RandomAccessFileInStream t = new RandomAccessFileInStream(randomAccessFile);
            if(inputFilePath.endsWith("rar")){
                inArchive = SevenZip.openInArchive(ArchiveFormat.RAR5, t);
            }
            else if(inputFilePath.endsWith("7z")){
                inArchive = SevenZip.openInArchive(ArchiveFormat.SEVEN_ZIP, t);
            }
            else{
                inArchive = SevenZip.openInArchive(ArchiveFormat.ZIP, t);
            }
            ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
            for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
                final int[] hash = new int[]{0};
                System.out.println("item.isFolder()==" + item.isFolder());
                if (!item.isFolder()) {
                    ExtractOperationResult result;
                    final long[] sizeArray = new long[1];
                    result = item.extractSlow(new ISequentialOutStream() {
                        public int write(byte[] data) throws SevenZipException {
                            //写入指定文件
                            FileOutputStream fos;
                            try {
                                if (item.getPath().indexOf(File.separator) > 0) {
                                    String path = targetFileDir + File.separator + item.getPath().substring(0, item.getPath().lastIndexOf(File.separator));
                                    File folderExisting = new File(path);
                                    if (!folderExisting.exists()){
                                        new File(path).mkdirs();
                                    }
                                }
                                fos = new FileOutputStream(targetFileDir + File.separator + item.getPath(), true);
                                fos.write(data);
                                fos.close();
                            }
                            catch (Exception e) {
                                e.printStackTrace();
                            }
                            hash[0] ^= Arrays.hashCode(data); // Consume data
                            sizeArray[0] += data.length;
                            return data.length; // Return amount of consumed data
                        }
                    });

                    if (result == ExtractOperationResult.OK) {
                        System.out.println(String.format("%9X | %10s | %s",hash[0], sizeArray[0], item.getPath()));
                    }
                    else {
                        System.err.println("Error extracting item: " + result);
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("Error occurs: " + e);
            e.printStackTrace();
            System.exit(1);
        } finally {
            if (inArchive != null) {
                try {
                    inArchive.close();
                } catch (SevenZipException e) {
                    System.err.println("Error closing archive: " + e);
                }
            }
            if (randomAccessFile != null) {
                try {
                    randomAccessFile.close();
                } catch (IOException e) {
                    System.err.println("Error closing file: " + e);
                }
            }
        }
    }



}

这里是解压rar 我测试一下没有问题,线上没有问题,但是客户那里测试出现问题,我看一天,没有发现什么异常,最后,同事说我来看看,因为同事电脑不存在直接压缩成rar 先压缩成zip,改成rar,上传就出现错误,我就想用以前大佬发给我,这个以前的博客写过

public class RARUtil {
    public static void main(String[] args) {
        File file = new File("C:\\Users\\lenovo\\Desktop\\图片");
        File[] tempList = file.listFiles();

        for (int i = 0; i < tempList.length; i++) {
            if (tempList[i].isFile()) {
                //这里不进行递归
                System.out.println(   tempList[i].getPath());
                System.out.println(tempList[i].getName());


                //文件名,不包含路径
                //String fileName = tempList[i].getName();
            }

        }
    }
    public static void decompressFile(String inputFilePath,final String targetFileDir) {
        //解压7zip文件
        RandomAccessFile randomAccessFile = null;
        IInArchive inArchive = null;
        try {
            // 判断目标目录是否存在,不存在则创建
            File newdir = new File(targetFileDir);
            if (false == newdir.exists()) {
                newdir.mkdirs();
                newdir = null;
            }
            randomAccessFile = new RandomAccessFile(inputFilePath, "r");
            RandomAccessFileInStream t = new RandomAccessFileInStream(randomAccessFile);
            if(inputFilePath.endsWith("rar")){
                inArchive = SevenZip.openInArchive(ArchiveFormat.RAR5, t);
            }
            else if(inputFilePath.endsWith("7z")){
                inArchive = SevenZip.openInArchive(ArchiveFormat.SEVEN_ZIP, t);
            }
            else{
                inArchive = SevenZip.openInArchive(ArchiveFormat.ZIP, t);
            }
            ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
            for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
                final int[] hash = new int[]{0};
                System.out.println("item.isFolder()==" + item.isFolder());
                if (!item.isFolder()) {
                    ExtractOperationResult result;
                    final long[] sizeArray = new long[1];
                    result = item.extractSlow(new ISequentialOutStream() {
                        public int write(byte[] data) throws SevenZipException {
                            //写入指定文件
                            FileOutputStream fos;
                            try {
                                if (item.getPath().indexOf(File.separator) > 0) {
                                    String path = targetFileDir + File.separator + item.getPath().substring(0, item.getPath().lastIndexOf(File.separator));
                                    File folderExisting = new File(path);
                                    if (!folderExisting.exists()){
                                        new File(path).mkdirs();
                                    }
                                }
                                fos = new FileOutputStream(targetFileDir + File.separator + item.getPath(), true);
                                fos.write(data);
                                fos.close();
                            }
                            catch (Exception e) {
                                e.printStackTrace();
                            }
                            hash[0] ^= Arrays.hashCode(data); // Consume data
                            sizeArray[0] += data.length;
                            return data.length; // Return amount of consumed data
                        }
                    });

                    if (result == ExtractOperationResult.OK) {
                        System.out.println(String.format("%9X | %10s | %s",hash[0], sizeArray[0], item.getPath()));
                    }
                    else {
                        System.err.println("Error extracting item: " + result);
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("Error occurs: " + e);
            e.printStackTrace();
            System.exit(1);
        } finally {
            if (inArchive != null) {
                try {
                    inArchive.close();
                } catch (SevenZipException e) {
                    System.err.println("Error closing archive: " + e);
                }
            }
            if (randomAccessFile != null) {
                try {
                    randomAccessFile.close();
                } catch (IOException e) {
                    System.err.println("Error closing file: " + e);
                }
            }
        }
    }



}

但是还是有问题,判断rar是null,™的,我就写的

   try {
            byte[] bytes =multipartFiles.getBytes();
            BufferedInputStream bufferedInputStream=new BufferedInputStream(new ByteArrayInputStream(bytes));
//        FileType fileType= FileTypeDetector
            com.drew.imaging.FileType fileType = FileTypeDetector.detectFileType(bufferedInputStream);
            if (!StringUtils.isEmpty(fileType.getMimeType())){
                if (!fileType.getMimeType().equals("application/x-rar-compressed")){
                    return -1;
                }
            }
        }catch (Exception e){
              return -1;
        }

解决这个问题 ,返回是-1就是上传格式有问题

参数校检

以前在前面说过 但是现在前端传递 一对多的数据格式怎么进行校检 传递的参数

@ApiModel("管理员实体类")
@Data
public class Admin implements Serializable, UserDetails {
    private static final long serialVersionUID = -75235725571250857L;

    private Integer id;
    /**
    * 登录账号
    */
    @ApiModelProperty("登录账号")
    @NotBlank(message = "账号不能为空")
    private String username;
    /**
    * 昵称
    */
    @ApiModelProperty("昵称")
    @NotBlank(message = "昵称不能为空")
    private String nickname;
    /**
    * 密码
    */
    @ApiModelProperty("密码")
    @NotBlank(message = "密码不能为空")
    private String password;
    /**
    * 管理员头像
    */
    @ApiModelProperty("管理员头像")
    private String userProfile;
    @NotEmpty(message = "用户列表不能是null")
    private List< @Valid User> users;
    @Data
public class User  implements UserDetails {

    private Integer id;
    /**
    * 登录账号
    */
    @NotBlank(message = "姓名不能是null")
    private String username;
    /**
    * 昵称
    */
    private String nickname;
    /**
    * 密码
    */
    private String password;
    /**
    * 用户头像
    */
    private String userProfile;
    /**
    * 用户状态id
    */
    private Integer userStateId;
    /**
    * 是否可用
    */
    private Boolean isEnabled;
    /**
    * 是否被锁定
    */
    private Boolean isLocked;

这个时候怎么进行校监全部的参数

控制层

  @PostMapping("/gg")
    public  RespBean  getqq1(@Validated @RequestBody Admin admin){
        //判断null

        return    RespBean.ok("成功",adminService.Queryallusers());
    }

处理错误

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public RespBean handler(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        ObjectError objectError = bindingResult.getAllErrors().stream().findFirst().get();
        return RespBean.error(objectError.getDefaultMessage());
    }

这个时候在校监参数加上@Valid ,不管是一对一还是一对多都进行校检了

@AssertFalse 所注解的元素必须是Boolean类型,且值为false
@AssertTrue 所注解的元素必须是Boolean类型,且值为true
@DecimalMax 所注解的元素必须是数字,且值小于等于给定的值
@DecimalMin 所注解的元素必须是数字,且值大于等于给定的值
@Digits 所注解的元素必须是数字,且值必须是指定的位数
@Future 所注解的元素必须是将来某个日期
@Max 所注解的元素必须是数字,且值小于等于给定的值
@Min 所注解的元素必须是数字,且值小于等于给定的值
@Range 所注解的元素需在指定范围区间内
@NotNull 所注解的元素值不能为null
@NotBlank 所注解的元素值有内容
@Null 所注解的元素值为null
@Past 所注解的元素必须是某个过去的日期
@PastOrPresent 所注解的元素必须是过去某个或现在日期
@Pattern 所注解的元素必须满足给定的正则表达式
@Size 所注解的元素必须是String、集合或数组,且长度大小需保证在给定范围之内
记住@NotBlank是字符串校监  @NotNull这个是万能的

事务的机制

Transactional  机制
propagation 属性
事务的传播行为,默认值为 Propagation.REQUIRED。可选的值有:

PROPAGATION.REQUIRED:如果当前没有事务,则创建一个新事务。如果当前存在事务,就加入该事务。该设置是最常用的设置。
PROPAGATION.SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务。如果当前不存在事务,就以非事务执行。
PROPAGATION.MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
PROPAGATION.REQUIRE_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
PROPAGATION.NOT_SUPPORTED:以非事务方式执行操作,如果当前事务存在,就把当前事务挂起。
PROPAGATION.NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION.NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按 REQUIRED 属性执行。 
比如现在有一段业务代码,方法 A 调用方法 B,我希望的是如果方法 A 出错了,此时仅仅回滚方法 A,不能回滚方法 B,这个时候可以给方法 B 使用 REQUIRES_NEW 传播机制,让他们两的事务是不同的。

如果方法 A 调用方法 B,如果出错,方法 B 只能回滚它自己,方法 A 可以带着方法 B 一起回滚。那这种情况可以给方法 B 加上 NESTED 嵌套事务。
1当第一条出现错误  第2条出现正确的时候这个时候使用注解@Transactional(propagation = Propagation.REQUIRED)  保证2条数据都回滚  意思就是2个数据处同一个事务下面
如果当前没有事务,则创建一个新事务。如果当前存在事务,就加入该事务。该设置是最常用的设置。
2 调用其他的方法出现异常了 ,不影响其他的方法  但是这个方法的sql进行回滚
在默认的代理模式下,只有目标方法由外部调用,才能被 Spring 的事务拦截器拦截。在同一个类中的两个方法直接调用,是不会被 Spring 的事务拦截器拦截,
就像上面的 save 方法直接调用了同一个类中 method1 方法,
method1 方法不会被 Spring 的事务拦截器拦截。可以使用 AspectJ 取代 Spring AOP 代理来解决这个问题。但是这里不展开。
当2个插入是一对多的关系,想一个错误就上面回滚,下面错误上面就回滚就使用
PROPAGATION.REQUIRED 进行

最后一个问题 mysql表中有一个数据字符串类型,以前也写过,但是我要以,进行分割加去重怎么写 代码

SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(message(x相当于图中的num),','(以,分割),b.help_topic_id + 1),',',-1) as  g
FROM  cstore_message_info(表)  INNER JOIN mysql.help_topic b ON b.help_topic_id < (LENGTH(cstore_message_info.message) - LENGTH(REPLACE(cstore_message_info.message, ',''')) + 1)  WHERE  cstore_message_info.id=1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值