/Articles

Java IO - PushbackInputStream判断Class文件有效性

PushbackInputStream可以让程序试探性地读取字节流的前若干个字节来判断是否该流是自己期望的。如果是,可以处理后续流数据。如果不是,可以回退读取的字节,把流交给其他人。 这个例子演示一个简单的场景,读取Java Class文件,判断是否是合法的Class 魔数是否为合法的"CAFEBABE" Major Version是否是期望的版本 首先查阅Java规范,可以知道Class的文件结构为: ClassFile { u4 magic; u2 minor_version; u2 major_version; u2...

Java IO - ObjectOutputStream串行化二进制数据分析

ObjectOutputStream和ObjectInputStream配对使用来处理实现了Serializable接口的对象。Serializable,串行化,这种计算机专用术语太过于拗口,如果按照我自己的解释,说得最通俗一点就是把对象里面各个需要写出的数据按照事先设计好的的规则和格式排列,组成一个二进制的数据行,写出到目标地。目标地再按照一定的格式把数据解析出来,还原成原始的对象。 串行化二进制文件格式分析 Java对于如何设计这个规则,有专门的文档(Object Serialization Stream Protocol)解释写出的数据的二进制各个标段的含义。...

Java IO - DataOutputStream/DataInputStream处理中文

DataOutputStream、DataInputStream可以将Java中的基本类型以类似对象的方式存储或读取,不再以字节方式处理,方法非常简单。但在处理中文字符时,存储方式就比较特殊。 基本类型的定长读写 Java基本类型都是定长的,也就是每个基本类型通过DataInputStream写入文件时,都是定长地写。在DataInputStream读取时不需要程序员考虑下一个类型从何处开始何处结束。比如整型为32位4字节长,浮点型为32位4字节长,boolean型非常特殊,有效值只是1个bit(0或1),size在官方JVM规范中也没有明确讲明,但在例子中可以看到它占用8位1个字节。...

Java IO - ByteArray流的重用

ByteArrayInputSteam类将内存中的字节数组作为数据源,利用这个特性,可以通过ByteArrayInputSteam重用一些需要特殊处理、或者重复使用的字节数组或大字符串,比如XML格式的内容。 一个有用的场景是对于异常的特殊处理。一般而言,我们简单地通过 Exception.printStackTrace()方法直接输出异常栈到标准输出stdout。 异常的一般性处理 try { int x = 1 / 0; // <--- } catch (Exception e) { e.printStackTrace(); }...

Java IO - FilterInputStreadm/FilterOutStream使用场景

FilterInputStream和FilterOutputStream的使用场景比较少,但是提供了一个可扩展的流处理的可能性,它采用了装饰者设计模式,FilterInputStream是所有具体装饰者的父类,内部包裹一个InputSteam的原始类作为被装饰对象,通过具体的FilterInputStream的子类实现来调用InputStream的流处理功能,并在流基础上附加额外的功能。 比如前面提到的BufferedInputStream,它就是装饰者子类实现,文件流的读取依然调用父类FilterInputStream所包裹的InputStream,但额外提供了内部buf的缓存功能。...

Java IO - 用SequenceInputStream合并文件

通过SequenceInputStream可以连接多个InputStream对象,按照排列顺序依次读取各个InputStream中的数据。这个特点很容易想到一个非常常见的场景,就是文件合并。下面的例子简单演示一个文件的拆分和合并的过程。 文件拆分 split函数根据指定的size参数,将文件拆分成每个size大小的小文件。按照 .1、 .2、 .3的顺序命名各个文件。 public static void split(String filename, int size){ try{ FileInputStream in = new...

Java IO - 带Buffer的文件二进制读写及问题

一般性文件的顺序读写提供的函数或者一个字节/字符地读写,或者以字节/字符数组的方式一次性读入一定数量的数据进入数组。后者其实相当于一个缓存。但JDK又额外提供了BufferedInputStream和BufferedOutputStream。他们的处理方式非常简单。 看个例子 String srcFile = "./test/qq.exe"; String destFile = "/test/qq2.exe"; try (BufferedInputStream bis = new BufferedInputStream(new...

Java IO - 基本文件的顺序读写

一般性文件的顺序读写有2种方式:基于二进制;基于字符。无论哪种方法都非常简单。但有一些细节比较重要。 顺序读写 下面的例子是最常见的读写顺序文件的方式,以FileInputStream/FileOutputStream或者FileReader/FileWriter来处理。 FileInputStream/FileOutputStream String filename1 = "./test/11.txt"; String filename2 = "./test/12.txt"; String filename3 = "./test/13.txt"; String filename4...

4 ways to secure JMX remote access

Many Java/JEE applications open the JMX interface/port to external for tuning or monitor purpose and most of them allow anonymous access. That is to say anyone knows the remote hostname and its JMX port can access/modify all exposed MBeans. I will show how to authenticate JMX access with following...

通过JMX对类路径问题进行诊断

Java应用类中经常会在生产环境碰到ClassNotFoundException之类的错误。对于一个庞大的Java应用来说,从成百上千的jar文件中去核查这个类很困难。除了这个错误之外,类似的和Class相关的错误还有: java.lang.NoClassDefFoundError java.lang.ClassNotFoundException java.lang.NoSuchMethodException java.lang.NoSuchMethodError...

线程分析-线程池溢出

Java中的线程池溢出,是个比较难诊断的问题。它的成因是多个任务(比如HTTP请求)等待执行,因为每个thread在一个时间点上只能执行一个task,如果线程池最多可以容纳20个线程,涌进来30个任务,那么只有20个任务才能得到执行,剩下的10个必须等待池中出现闲置的线程。如果有一些执行的任务很耗时,后面的任务将长时间得不到线程资源供执行,线程池溢出的问题就会发生。 很多web服务器都提供了线程池的技术,可以动态扩展,但都有一定的限额。下面的代码演示线程池溢出的问题,代码相对复杂,但能很好地解释这个现象。 代码演示...

线程分析-资源竞争

Java线程问题中最为常见的成因是资源竞争,它导致的后果是服务器停止响应,或者CPU过高使用。资源竞争非常好理解,就是一个或者多个线程等待某个资源,而这个资源又被另一个线程所占有并长时间不能释放。对于这种情形,Thread Dump中的“waiting for monitor entry”就非常重要。 代码演示...

1 2 3