diff --git a/group24/315863321/src/main/java/jvm/loader/ClassFileLoader.java b/group24/315863321/src/main/java/jvm/loader/ClassFileLoader.java new file mode 100644 index 0000000000..a300edafc7 --- /dev/null +++ b/group24/315863321/src/main/java/jvm/loader/ClassFileLoader.java @@ -0,0 +1,57 @@ +package jvm.loader; + + +import com.johnChnia.coding2017.basic.ArrayList; +import com.johnChnia.coding2017.basic.List; + +import java.io.*; + +/** + * @// TODO: 2017/4/20 改成 try... with...resource + * @// TODO: 2017/4/20 close inputstream + * @// TODO: 2017/4/20 修改TreeInfo直接返回File + */ +public class ClassFileLoader { + + private List clzPaths = new ArrayList(); + + public byte[] readBinaryCode(String className) { + for (int i = 0; i < clzPaths.size(); i++) { + // 找到指定类文件 + Directory.TreeInfo treeInfo = Directory.walk(clzPaths.get(i), className); + if (treeInfo.files.size() > 0) { + try { + FileInputStream fis = new FileInputStream(treeInfo.files.get(0)); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); // 自动增长 + byte[] buff = new byte[1024]; + int len; + while ((len = fis.read(buff)) != -1) { + bos.write(buff, 0, len); + } + return bos.toByteArray(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return null; + + } + + + public void addClassPath(String path) { + clzPaths.add(path); + } + + + public String getClassPath() { + StringBuilder sb = new StringBuilder(); + for (int index = 0; index < clzPaths.size(); index++) { + sb.append(clzPaths.get(index)); + sb.append(";"); + } + return sb.toString().substring(0, sb.length() - 1); + } + + +} diff --git a/group24/315863321/src/main/java/jvm/loader/Directory.java b/group24/315863321/src/main/java/jvm/loader/Directory.java new file mode 100644 index 0000000000..98f239434d --- /dev/null +++ b/group24/315863321/src/main/java/jvm/loader/Directory.java @@ -0,0 +1,81 @@ +package jvm.loader; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.regex.Pattern; + +/** + * Created by john on 2017/4/17. + * + * @// TODO: 2017/4/20 实现 List.addAll(), list implements Iterable + */ +public final class Directory { + + public static File[] local(File dir, final String regex) { + return dir.listFiles(new FilenameFilter() { // 文件过滤接口 + private Pattern pattern = Pattern.compile(regex); + + @Override + public boolean accept(File dir, String name) { + return pattern.matcher(new File(name).getName()).matches(); + } + }); + } + + public static File[] local(String path, final String regex) { + return local(new File(path), regex); + } + + public static class TreeInfo implements Iterable { + public List files = new ArrayList<>(); + public List dirs = new ArrayList<>(); + + @Override + public Iterator iterator() { + return files.iterator(); + } + + public void addAll(TreeInfo other) { + files.addAll(other.files); + dirs.addAll(other.dirs); + } + + @Override + public String toString() { + return "dirs: " + dirs + + "\n\nfiles: " + files; + } + } + + public static TreeInfo walk(String start, String regex) { + return recuresDirs(new File(start), regex); + } + + public static TreeInfo walk(File start, String regex) { + return recuresDirs(start, regex); + } + + public static TreeInfo walk(File start) { + return recuresDirs(start, ".*");// 全部 + } + + public static TreeInfo walk(String start) { + return recuresDirs(new File(start), ".*");// 全部 + } + + public static TreeInfo recuresDirs(File startDir, String regex) { + TreeInfo result = new TreeInfo(); + for (File item : startDir.listFiles()) { + if (item.isDirectory()) { + result.dirs.add(item); + result.addAll(recuresDirs(item, regex)); + } else if (item.getName().matches(regex)) + result.files.add(item); + } + return result; + } + +} \ No newline at end of file diff --git a/group24/315863321/src/main/java/jvm/test/ClassFileloaderTest.java b/group24/315863321/src/main/java/jvm/test/ClassFileloaderTest.java new file mode 100644 index 0000000000..70d400cb28 --- /dev/null +++ b/group24/315863321/src/main/java/jvm/test/ClassFileloaderTest.java @@ -0,0 +1,83 @@ +package jvm.test; + +import jvm.loader.ClassFileLoader; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +public class ClassFileloaderTest { + + + static String path1 = "/Users/john/Documents/mygit/coding2017/group24/315863321/target/classes/jvm"; + static String path2 = "/Users/john/Documents"; + + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testClassPath() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + loader.addClassPath(path2); + + String clzPath = loader.getClassPath(); + + Assert.assertEquals(path1 + ";" + path2, clzPath); + + } + + @Test + public void testClassFileLength() { + + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + + String className = "EmployeeV1.class"; + + byte[] byteCodes = loader.readBinaryCode(className); + + // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 + Assert.assertEquals(1026, byteCodes.length); + + } + + + @Test + public void testMagicNumber() { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "EmployeeV1.class"; + byte[] byteCodes = loader.readBinaryCode(className); + byte[] codes = new byte[]{byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3]}; + + + String acctualValue = this.byteToHexString(codes); + + Assert.assertEquals("cafebabe", acctualValue); + } + + + private String byteToHexString(byte[] codes) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < codes.length; i++) { + byte b = codes[i]; + int value = b & 0xFF; + String strHex = Integer.toHexString(value); + if (strHex.length() < 2) { + strHex = "0" + strHex; + } + buffer.append(strHex); + } + return buffer.toString(); + } + +} diff --git a/group24/315863321/src/main/java/jvm/test/EmployeeV1.java b/group24/315863321/src/main/java/jvm/test/EmployeeV1.java new file mode 100644 index 0000000000..3fbdcef7bf --- /dev/null +++ b/group24/315863321/src/main/java/jvm/test/EmployeeV1.java @@ -0,0 +1,31 @@ +package jvm.test; + +public class EmployeeV1 { + + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + + public void setAge(int age) { + this.age = age; + } + + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + + public static void main(String[] args) { + EmployeeV1 p = new EmployeeV1("Andy", 29); + p.sayHello(); + + } +} \ No newline at end of file