import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* 校验Class文件版本。
*
* @author wml
*
*/
public class ValidateClassVersionTools
{
// Class版本
enum ClassVersion
{
// 定义Class版本数据
JDK4("46.0", "1.4"), JDK5("49.0", "1.5"), JDK6("50.0", "1.6");
private String version; // Class版本号
private String alias; // Class版本别名
private ClassVersion(String version, String alias)
{
this.version = version;
this.alias = alias;
}
/**
* 通过Class版本号获取Class版本别名。 若版本号不存在则返回null。
*
* @param version
* 版本号。
* @return 别名。
*/
public static String getAlias(String version)
{
for (ClassVersion c : ClassVersion.values())
{
if (c.version.equals(version))
{
return c.alias;
}
}
return null;
}
/**
* 通过Class版本号获取ClassVersion。 若版本号不存在则返回null。
*
* @param version
* @return
*/
public static ClassVersion getClassVersion(String version)
{
for (ClassVersion c : ClassVersion.values())
{
if (c.version.equals(version))
{
return c;
}
}
return null;
}
public String toString()
{
return version + ":" + alias;
}
public String getVersion()
{
return version;
}
public String getAlias()
{
return alias;
}
}
// 版本号对应:
// 5.0
// 版本号(version):49.0
// 6.0
// 版本号(version):50.0
// 1.4
// 版本号(version):46.0
// 1.3
// 版本号(version):45.3
public static ClassVersion getVersion(String classFilePath)
throws IOException
{
InputStream in = new FileInputStream(classFilePath);
int length = in.available();
// 文件数据
byte[] data = new byte[length];
// 读取文件到字节数组
in.read(data);
// 关闭文件
in.close();
// 解析文件数据
return parseFile(data);
}
public static void printlnDirClassesVersion(String classDir) throws IOException
{
List<String> filePaths = new ArrayList<String>();
loadFilePaths(classDir, filePaths);
for (String classFilePath : filePaths)
{
System.out.println(getVersion(classFilePath).toString() + ":" + classFilePath);
}
}
// 递归获取目录的文件地址
private static void loadFilePaths(String path, List<String> filePathList) {
File f = new File(path);
File[] fs = f.listFiles();
if (fs == null) {
return;
}
for (File file : fs) {
if (file.isFile()) {
if (file.getPath().endsWith("class")){
filePathList.add(file.getPath());
}
} else {
loadFilePaths(file.getPath(), filePathList);
}
}
return;
}
private static ClassVersion parseFile(byte[] data)
{
// 输出魔数
/*
System.out.print("魔数(magic):0x");
System.out.print(Integer.toHexString(data[0]).substring(6)
.toUpperCase());
System.out.print(Integer.toHexString(data[1]).substring(6)
.toUpperCase());
System.out.print(Integer.toHexString(data[2]).substring(6)
.toUpperCase());
System.out.println(Integer.toHexString(data[3]).substring(6)
.toUpperCase());
*/
// 主版本号和次版本号码
int minor_version = (((int) data[4]) << 8) + data[5];
int major_version = (((int) data[6]) << 8) + data[7];
String version = major_version + "." + minor_version;
return ClassVersion.getClassVersion(version);
}
public static void main(String[] args)
{
final String findClassDir = "D:\\Workspaces\\bin";
try
{
ValidateClassVersionTools.printlnDirClassesVersion(findClassDir);
} catch (IOException e)
{
e.printStackTrace();
}
}
}
|