读取 calss文件

标签: calss 文件 | 发表时间:2014-03-18 19:57 | 作者:
出处:http://m635674608.iteye.com
import java.io.*;

public class ClassAnalyzer {
	public static StringBuffer sb = new StringBuffer();
	public static byte[] analyzeConstant_tag;
	public static String[] analyzeConstant_utf8;
	public static DataOutputStream dataout;

	public static void main(String[] args) {
		DataInputStream input = null;
		try {
			FileOutputStream out = new FileOutputStream(
					"d:\\home\\1.txt");
			BufferedOutputStream buffout = new BufferedOutputStream(out);
			dataout = new DataOutputStream(buffout);

			input = new DataInputStream(
					new BufferedInputStream(
							new FileInputStream(
									"D:\\Workspaces\\MyEclipse 9.2\\test\\bin\\TestClass.class")));
			// 获取文件大小
			FileSize(new DataInputStream(
					new BufferedInputStream(
							new FileInputStream(
									"D:\\Workspaces\\MyEclipse 9.2\\test\\bin\\TestClass.class"))));
			// 解析数据
			analyze(input);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("解析失败!");
		} finally {
			try {
				input.close();
				dataout.close();
			} catch (Exception e) {
			}
		}
	}

	public static void FileSize(DataInputStream input) throws IOException {
		int length = 0; // 长度,字节,B
		double kblength = 0.0D; // 长度,千字节,KB
		while (input.read() != -1)
			++length;
		kblength = length / 1024.0D;
		System.out.println("文件大小(字节):" + length + "\n文件大小(KB):" + kblength);
		input.close();
	}

	public static void analyze(DataInputStream input) throws IOException {
		// 读取幻数
		int magic = u4(input);
		if (magic == 0xCAFEBABE) // -889275714
			System.out.println("magic number = 0xCAFEBABE -----标准class文件");
		else {
			throw new RuntimeException("无效的幻数!");
		}
		// 读取副、主版本号
		int minor_ver = u2(input);
		int major_ver = u2(input);
		System.out.println("Version = " + major_ver + "." + minor_ver);
		add("    常规信息    ");
		add("Minor version:    " + minor_ver);
		add("Major version:    " + major_ver);
		// 读取常量池表中表项的个数
		short const_pool_count = u2(input);
		System.out.println("constant pool size = " + const_pool_count);
		add("Constant pool count:    " + const_pool_count);
		// 读取每个常量
		analyzeConstant_tag = new byte[const_pool_count]; // 存储常量数据类型
		analyzeConstant_tag[0] = 0; // 系统保留,class中不存在
		for (int i = 1; i < const_pool_count; ++i)
			analyzeConstant(input, i); // 分析常数
		jiexitmp(); // 解析tmp文件
		// 读取Class的声明中使用的修饰符掩码并解析
		short access_flags = u2(input);
		System.out.print("access_flags = " + access_flags);
		String access_flags_16 = "0x" + Integer.toHexString(access_flags);
		int[] access = { 0x0001, 0x0010, 0x0020, 0x0200, 0x0400 };
		String[] access_str = { "public", "final", "", "interface", "abstract" }; // NO.2--super
		String access_tmp = "";
		for (int i = 0; i < access.length; i++) {
			if ((access_flags & access[i]) == access[i]) {
				if (i == 0)
					access_tmp += access_str[i];
				else if (i != 2)
					access_tmp += " " + access_str[i];
			}
		}
		System.out.println(" [" + access_tmp + " ]");
		add("Access flags:    " + access_flags_16 + " [" + access_tmp + " ]");
		// 读取类或者接口的全限定名称
		short this_class_index = u2(input);
		short super_class_index = u2(input);
		System.out.println("This class = " + this_class_index);
		System.out.println("Super class = " + super_class_index);
		add("This class:    " + this_class_index);
		add("Super class:    " + super_class_index);
		// read interfaces count:
		short interfaces_count = u2(input);
		System.out.println("超接口个数 = " + interfaces_count);
		add("Interfaces count:    " + interfaces_count);
		// read each interface:
		for (int i = 1; i <= interfaces_count; i++) {
			short interface_index = u2(input);
			System.out.println("No. " + i + " interface index = "
					+ interface_index);
		}
	}

	public static byte u1(DataInputStream input) throws IOException {
		return input.readByte();
	}

	public static Short u2(DataInputStream input) throws IOException {
		return input.readShort();
	}

	public static int u4(DataInputStream input) throws IOException {
		return input.readInt();
	}

	public static long u8(DataInputStream input) throws IOException {
		return input.readLong();
	}

	public static void add(String str) throws IOException {
		sb.append(str + "\n");
	}

	public static void analyzeConstant(DataInputStream input, int index)
			throws IOException {
		// 用于读:
		byte n8;
		short n16;
		int n32;
		long n64;
		float f;
		double d;
		byte[] buffer;
		byte tag = input.readByte(); // 读取数据类型标签
		analyzeConstant_tag[index] = tag; // 存储常量数据类型
		System.out.println("\n常量索引 = " + index + ", 数据类型标签 = " + (int) tag);
		switch (tag) {
		case 1: // utf-8 string
			System.out.println(" 常量类型 = Utf8 //Utf8存储格式"); // Utf8存储格式
			n16 = u2(input);
			System.out.println("     length = " + n16);
			dataout.writeShort(n16);
			buffer = new byte[n16];
			input.readFully(buffer); // 数组读满才返回
			System.out.println("      value = " + new String(buffer));
			dataout.writeUTF(new String(buffer));
			break;
		case 3: // integer
			System.out.println(" 常量类型 = Integer //Integer存储格式"); // Integer存储格式
			n32 = u4(input);
			System.out.println("      value = " + n32);
			dataout.writeInt(n32);
			break;
		case 4: // float
			System.out.println(" 常量类型 = Float //Float存储格式"); // Float存储格式
			f = u4(input);// input.readFloat();
			System.out.println("      value = " + f);
			dataout.writeFloat(f);
			break;
		case 5: // long
			System.out.println(" 常量类型 = Long //Long存储格式"); // Long存储格式
			n64 = u8(input);
			System.out.println("      value = " + n64);
			dataout.writeLong(n64);
			break;
		case 6: // double
			System.out.println(" 常量类型 = Double //Double存储格式"); // Double存储格式
			d = u8(input);
			System.out.println("      value = " + d);
			dataout.writeDouble(d);
			break;
		case 7: // class or interface reference
			System.out.println(" 常量类型 = Class //类索引"); // 类索引
			n16 = u2(input);
			System.out.println("      index = " + n16 + " (在哪里可以找到类名)");
			dataout.writeShort(n16);
			break;
		case 8: // string
			System.out.println(" 常量类型 = String //字符串索引"); // 字符串索引
			n16 = u2(input);
			System.out.println("      index = " + n16);
			dataout.writeShort(n16);
			break;
		case 9: // field reference
			System.out.println(" 常量类型 = Fieldref //领域参数"); // 领域参数
			n16 = u2(input);
			System.out.println("class index = " + n16 + " (在哪里可以找到类名)");
			dataout.writeShort(n16);
			n16 = u2(input);
			System.out.println("nameAndType = " + n16 + " (在哪里可以找到的名称和类型)");
			dataout.writeShort(n16);
			break;
		case 10: // method reference
			System.out.println(" 常量类型 = Methodref //方法参考"); // 方法参考
			n16 = u2(input);
			System.out.println("class index = " + n16 + " (在哪里可以找到类)");
			dataout.writeShort(n16);
			n16 = u2(input);
			System.out.println("nameAndType = " + n16 + " (在哪里可以找到名称和类型)");
			dataout.writeShort(n16);
			break;
		case 11: // interface method reference
			System.out.println(" 常量类型 = InterfaceMethodref //接口方法参考值"); // 接口方法参考值
			n16 = u2(input);
			System.out.println("class index = " + n16 + " (在哪里可以找到接口)");
			dataout.writeShort(n16);
			n16 = u2(input);
			System.out.println("nameAndType = " + n16 + " (在哪里可以找到名称和类型)");
			dataout.writeShort(n16);
			break;
		case 12: // name and type reference
			System.out.println(" 常量类型 = NameAndType //名称和类型"); // 名称和类型
			n16 = u2(input);
			System.out.println(" name index = " + n16 + " (在哪里可以找到这个名字)");
			dataout.writeShort(n16);
			n16 = u2(input);
			System.out.println(" descripter = " + n16 + " (在哪里可以找到描述符)");
			dataout.writeShort(n16);
			break;
		default:
			throw new RuntimeException("Invalid constant pool flag: " + tag);
		} // end switch
	}

	public static void jiexitmp() {
		DataInputStream input = null;
		try {
			input = new DataInputStream(
					new BufferedInputStream(
							new FileInputStream(
									"C:\\Documents and Settings\\Administrator\\桌面\\解析class文件\\ReadClass.tmp")));
			/********** analyzeConstant_tag[]存储常量池表中常量数据类型(共11种) **********/
			int[] tagSpecies = new int[11]; // 存储常量池表中常量各种数据类型的计数
			int const_pool_count = analyzeConstant_tag.length; // 读取常量池表中表项的个数
			for (int i = 0; i < const_pool_count; i++) // 对数据类型的计数数组进行赋值
			{
				System.out.println(analyzeConstant_tag[i]); // 按顺序输出各种数据的类型
				switch (analyzeConstant_tag[i]) {
				case 1:
					++tagSpecies[0];
					break;
				case 3:
					++tagSpecies[1];
					break;
				case 4:
					++tagSpecies[2];
					break;
				case 5:
					++tagSpecies[3];
					break;
				case 6:
					++tagSpecies[4];
					break;
				case 7:
					++tagSpecies[5];
					break;
				case 8:
					++tagSpecies[6];
					break;
				case 9:
					++tagSpecies[7];
					break;
				case 10:
					++tagSpecies[8];
					break;
				case 11:
					++tagSpecies[9];
					break;
				case 12:
					++tagSpecies[10];
					break;
				}
			}
			for (int i = 0; i < tagSpecies.length; i++)
				System.out.println("数量" + tagSpecies[i]);/*
														 * analyzeConstant_utf8
														 * = new String[
														 * analyzeConstant_utf8_num
														 * ]; int j = 0; for(int
														 * i
														 * =0;i<const_pool_count
														 * ;i++)
														 * if(analyzeConstant_tag
														 * [i]==1)
														 * analyzeConstant_utf8
														 * [j++] = "r"; for(int
														 * i
														 * =0;i<analyzeConstant_utf8
														 * .length;i++)
														 * System.out
														 * .println("NO."+i+" "+
														 * analyzeConstant_utf8
														 * [i]);
														 */
		} catch (Exception e) {
			System.out.println("解析失败!");
		} finally {
			try {
				input.close();
			} catch (Exception e) {
			}
		}
	}

} // End

/*****
 * byte u1 Short u2 int u4 ClassFile表结构 ClassFile { u4 magic; //幻数 u2
 * minor_version; //副版本号 u2 major_version; //主版本号 u2 constant_pool_count;
 * //常量池表中表项的个数 cp_info constant_pool[constant_pool_count-1]; //每个常量的信息 u2
 * access_flags; //类修饰符掩码 u2 this_Class; //类或者接口的全限定名称 u2 super_Class; //父类全限定名称
 * u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count;
 * field_info fields[fields_count]; u2 methods_count; method_info
 * methods[methods_count]; u2 attributes_count; attribute_info
 * attributes[attributes_count]; }
 * 
 * 1//Utf8存储格式 dataout.writeShort(n16); //length dataout.writeUTF(new
 * String(buffer)); //字符串 3//Integer存储格式 dataout.writeInt(n32); 4//Float存储格式
 * dataout.writeFloat(f); 5//Long存储格式 dataout.writeLong(n64); 6//Double存储格式
 * dataout.writeDouble(d); 7//类索引 dataout.writeShort(n16); 8//字符串索引
 * dataout.writeShort(n16); 9//领域参数 dataout.writeShort(n16); //类名
 * dataout.writeShort(n16); //名称和类型 10//方法参考 dataout.writeShort(n16); //类名
 * dataout.writeShort(n16); //名称和类型 11//接口方法参考值 dataout.writeShort(n16); //接口
 * dataout.writeShort(n16); //名称和类型 12//名称和类型 dataout.writeShort(n16); //名字索引
 * dataout.writeShort(n16); //描述符索引
 *****/

    转载 http://www.360doc.com/content/10/0913/04/3317721_53227485.shtml



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [calss 文件] 推荐:

读取 calss文件

- - zzm
System.out.println("解析失败. int length = 0; // 长度,字节,B. double kblength = 0.0D; // 长度,千字节,KB. System.out.println("文件大小(字节):" + length + "\n文件大小(KB):" + kblength);.

python 下载文件

- Eric - python相关的python 教程和python 下载你可以在老王python里寻觅
之前给大家分享的python 多线程抓取网页,我觉的大家看了以后,应该会对python 抓取网页有个很好的认识,不过这个只能用python 来抓取到网页的源代码,如果你想用做python 下载文件的话,上面的可能就不适合你了,最近我在用python 做文件下载的时候就遇到这个问题了,不过最终得以解决,为了让大家以后碰过这个问题有更好的解决办法,我把代码发出来:.

Ext文件系统

- Haides - 博客园-首页原创精华区
  虽然从Ext2到Ext4,找数据的方式发生了变化,但是,磁盘的布局还是非常相似的. 其实这个东西也不需要变化,因为现在也没什么特别巧妙的方式,而且磁盘的吞吐量、效率的瓶颈也不在这里. 当然,这里排除那些根据自身文件特点设计的数据库,毕竟还是为了支持通用文件.   Boot在第一个块,放的应该是引导程序,超级块就放在了第二个块上,如果不是可以在mount的时候通过参数sb来设置.

Linux 文件结构

- Shiina Luce - OSMSG
想了解 Linux 文件系统树形结构,却又不愿翻阅 FHS 的朋友,可以参考 skill2die4 制作的这张简图. 此图算是 FHS 的图形化版本,简要的说明了 Linux 系统中各个目录的用途及层级关系,适合初学者使用参考. 不过其中较新的如 /run 目录并未在其中出现. 做为参考,这是 Fedora 16 Beta i686 上的文件结构:.

多文件上传

- - BlogJava-首页技术区
多文件上传 jquery的插件. 使用的方法  导入 jquery.js 及 jquery.MultiFile.js ,. 方式一: 后台是文件数组  .  private File[] upload; // 与jsp表单中的名称对应. 在 form 中加入 即可.

Zookeeper配置文件

- - 学着站在巨人的肩膀上
复制conf/zoo_sample.cfg文件为conf/zoo.cfg,修改其中的数据目录. tickTime:这个时间作为Zookeeper服务器之间或者服务器与客户端之间维护心跳的时间,时间单位毫秒. initLimit:选举leader的初始延时. 由于服务器启动加载数据需要一定的时间(尤其是配置数据非常多),因此在选举 Leader后立即同步数据前需要一定的时间来完成初始化.

Flume监听文件夹中的文件变化_并把文件下沉到hdfs

- - 行业应用 - ITeye博客
摘要: 1、采集目录到HDFS 采集需求:某服务器的某特定目录下,会不断产生新的文件,每当有新文件出现,就需要把文件采集到HDFS中去 根据需求,首先定义以下3大要素 采集源,即source——监控文件目录 : spooldir 下沉目标,即sink——HDFS文件系统 : hdfs sink source和sink之间的传递通道——channel,可用file chann.

Marlin: Elementary 文件管理器

- 加州旅客 - LinuxTOY
如果您喜好 OS X Finder 风格的文件管理器,Marlin 必然适合您. Marlin 文件管理器作为 Elementary OS 项目的一部分由 ammonkey 开发. Marlin 拥有如同 Finder 的列表视图:. 以及小小的选择 + 号和单击启动模式:. 现在 Marlin 测试版本的 PPA 仓库已经上线,在 Ubuntu 11.04 中安装,请进行:.

Linux 2.6 中的文件锁

- Mountain - 小程序员的草稿箱
在多任务操作系统环境中,如果一个进程尝试对正在被其他进程读取的文件进行写操作,可能会导致正在进行读操作的进程读取到一些被破坏或者不完整的数据;如果两个进程并发对同一个文件进行写操作,可能会导致该文件遭到破坏. 因此,为了避免发生这种问题,必须要采用某种机制来解决多个进程并发访问同一个文件时所面临的同步问题,由此而产生了文件加锁方面的技术.