package mini_jvm.loader;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class ClassFileLoader {
private List<String> clzPaths = new ArrayList<String>();
/**
* 读取class文件的二进制代码
* @param className
* @return
*/
public byte[] readBinaryCode(String className) {
String clazzPath = getClassPath(className);
BufferedInputStream bins = null;
ByteArrayOutputStream bouts = new ByteArrayOutputStream();
try {
bins = new BufferedInputStream(new FileInputStream(new File(clazzPath)));
byte[] buffer = new byte[1024];
int length = -1;
while((length = bins.read(buffer)) != -1){
bouts.write(buffer, 0, length);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
byte[] codes = bouts.toByteArray();
//关闭流
try {
if(bins != null){
//调用外层流的close方法就关闭其装饰的内层流
bins.close();
}
if(bouts != null){
bouts.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return codes;
}
/**
* 从扫描根目录,获取指定类的绝对路径
* @param className
* @return
*/
private String getClassPath(String className){
String clazzPath = null;
//遍历clzPaths中所有路径
for (String path : this.clzPaths){
File file = new File(path);
clazzPath = getClassPath(className,file);
if(clazzPath!=null) break;
}
return clazzPath;
}
private String getClassPath(String className, File file){
String clazzPath = null;
if(file.exists()){
//如果是目录,则遍历所有目录下的文件
if(file.isDirectory()){
File[] fs = file.listFiles();
for (File f : fs){
clazzPath = getClassPath(className,f);
}
}else {
//检查是否是该类对应的class文件
if(isClazzFile(file.getName(),className)){
clazzPath = file.getAbsolutePath();
}
}
}
return clazzPath;
}
private boolean isClazzFile(String filename , String className){
String fileClazzName = null;
String [] names = filename.split("\\.");
if(names.length > 0){
fileClazzName = names[0];
}
return className.endsWith(fileClazzName);
}
public void addClassPath(String path) {
clzPaths.add(path);
}
public String getClassPath(){
StringBuilder sb = new StringBuilder();
int i = 0;
for (; i < clzPaths.size() - 1; i++) {
sb.append(clzPaths.get(i));
sb.append(";");
}
sb.append(clzPaths.get(i));
return sb.toString();
}
}