检查java的class文件版本

发布时间 2023-04-21 10:41:25作者: 新手娃娃菜

 

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class CheckClassVersion {
    public static void main(String[] args) {
        checkFilesInDir("D:/test", JDKVERSION.JDK8);
    }

    private static Map<Integer, String> map = new HashMap<Integer, String>(30);
    static {
        JDKVERSION[] values = JDKVERSION.values();
        for (JDKVERSION val : values) {
            map.put(val.getValue(), val.getName());
        }
    }
    
    /**
     * 检查文件夹中class文件版本号
     * @param dirPath
     * @param jdkVersion
     */
    public static void checkFilesInDir(String dirPath, JDKVERSION jdkVersion) {
        if (dirPath == null) {
            System.out.println("传入路径为空。");
            return;
        }
        if (dirPath.endsWith("\\")) {
            dirPath = dirPath.replaceAll("\\", "/");
        }

        File path = new File(dirPath);
        if (!path.exists()) {
            System.out.println(dirPath + "路径不存在。");
            return;
        }

        File[] files = path.listFiles();
        if (files != null && files.length > 0) {
            for (File file : files) {
                getNames(file, file.getPath(), jdkVersion);
            }
        }
    }

    /**
     * 检查单个class文件版本
     * 
     * @param file
     * @param checkVersion
     * @return true:版本相同;false:版本不同
     */
    public static boolean check(String file, JDKVERSION jdkVersion) {
        if (!file.endsWith(".class")) {
            System.out.println(file + " 非class文件");
            return false;
        }
        FileInputStream fis = null;
        byte[] b = null;
        try {
            fis = new FileInputStream(file);
            b = new byte[8];
            try {
                int read = fis.read(b, 0, 8);
                if (read != 8) {
                    System.out.println(" 文件读取错误");
                    return false;
                }

                int fileVersion = parseFile(b);

                StringBuffer sb = new StringBuffer();
                sb.append(file);
                sb.append(" jdk版本:");
                sb.append(map.get(fileVersion));
                System.out.println(sb.toString());

                if (jdkVersion.getValue() == fileVersion) {
                    return true;
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (b != null) {
                b = null;
            }
        }

        return false;
    }

    /**
     * 返回主版本号
     * 
     * @param data
     * @return
     */
    private static int parseFile(byte[] data) {
        StringBuffer sb = new StringBuffer();
        sb.append("魔数(magic):0x");
        sb.append(Integer.toHexString(data[0]).substring(6).toUpperCase());
        sb.append(Integer.toHexString(data[1]).substring(6).toUpperCase());
        sb.append(Integer.toHexString(data[2]).substring(6).toUpperCase());
        sb.append(Integer.toHexString(data[3]).substring(6).toUpperCase());
        sb.append(" 版本号(version):");
        int minor_version = (((int)data[4]) << 8) + data[5];// 次版本号
        int major_version = (((int)data[6]) << 8) + data[7];// 主版本号
        sb.append(major_version);
        sb.append(".");
        sb.append(minor_version);
        // System.out.println(sb.toString());

        return major_version;
    }

    private static void getNames(File file, String parentName, JDKVERSION jdkVersion) {
        if (file == null) {
            return;
        }

        if (file.isDirectory()) {
            String pathName = file.getPath();
            File[] files = file.listFiles();
            if (files == null || files.length == 0) {
                return;
            }
            for (File f : files) {
                getNames(f, pathName, jdkVersion);
            }
        } else if (file.isFile()) {
            String fileName = file.getPath();

            boolean flag = check(fileName, jdkVersion);
            if (!flag) {
                System.out.println(fileName + " 校验版本未通过,传入参数中预期的版本号是:" + jdkVersion);
            }
        }
        return;
    }

}

/**
 * jdk版本号
 * 
 * @author jinzhm
 *
 */
enum JDKVERSION {
    JDK1(45, "JDK1"), JDK2(46, "JDK2"), JDK3(47, "JDK3"), JDK4(48, "JDK4"), JDK5(49, "JDK5"), JDK6(50, "JDK6"), JDK7(
        51, "JDK7"), JDK8(52, "JDK8"), JDK9(53, "JDK9"), JDK10(54, "JDK10"), JDK11(55, "JDK11"), JDK12(56, "JDK12"),
    JDK13(57, "JDK13"), JDK14(58, "JDK14"), JDK15(59, "JDK15"), JDK16(60, "JDK16"), JDK17(61, "JDK17");

    private int value;
    private String name;

    private JDKVERSION(int value, String name) {
        this.value = value;
        this.name = name;
    }

    public int getValue() {
        return value;
    }

    public String getName() {
        return name;
    }
}