package minijvm.loader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import minijvm.clz.ClassFile;
public class ClassFileLoader {
private List<String> clzPaths = new ArrayList<String>();
public byte[] readBinaryCode(String className) throws ClassNotFoundException {
File classFile = getClassFile(className);
return readFileToByteArray(classFile);
}
private File getClassFile(String className) throws ClassNotFoundException {
File classFile = null;
String classFilePath = convertClassNameToFilePath(className);
for (String path : clzPaths) {
File file = new File(path, classFilePath);
if (file.exists()) {
classFile = file;
break;
}
}
if (classFile == null) { // 文件不存在
throw new ClassNotFoundException();
}
return classFile;
}
private byte[] readFileToByteArray(File classFile) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (InputStream in = new FileInputStream(classFile);) {
byte[] data = new byte[1024];
int len = -1;
while ((len = in.read(data)) != -1) {
out.write(data, 0, len);
}
} catch (FileNotFoundException e) { // 调用此函数时,已经确定文件是存在的
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
return out.toByteArray();
}
private String convertClassNameToFilePath(String fillClassName) {
return fillClassName.replace(".", File.separator) + ".class";
}
public void addClassPath(String path) {
if (clzPaths.contains(path)) {
return;
}
clzPaths.add(path);
}
public String getClassPath() {
return String.join(";", clzPaths);
}
public ClassFile loadClass(String className) throws ClassNotFoundException {
byte[] codes = this.readBinaryCode(className);
ClassFileParser parser = new ClassFileParser();
return parser.parse(codes);
}
}