仿C# BinaryReader 读取二进制文件的Java实现代码

最近手头的活儿暂告一段落,正好有时间整理一下前面做的一个项目,在某些时候,我们需要读取一个格式明确的二进制文件,由于格式确定,我们还需要按照位数来读取相对应的内容(例如,我们需要读取第44位到第56位的这12个字节),说到这儿,很多人大概都会说,这有什么难的,Java读取二进制的方法有一大堆,随便找一个都可以读取,的确,Java的读取方法有很多,但是似乎没有一个读取一个字节就会让当前字节位提升一位的方法,如果你需要按照某个字节来读取,就会出现问题(当然,如果利用复制数组来“曲线救国”,那就另当别论)。

由于C#里的 BinaryReader 其中包含的很多读取二进制的方法都不错,关键是都会自动提升位数,所以就仿着写了一个可以自动提升的工具类BinaryReaderJ,废话不多说,直接上代码:

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
 * 仿C#BinaryReader的java方法
 * @author RKGG
 * @version 1.0
 * */
public class BinaryReaderJ {
	
	
	private static File file;
	private static InputStream in;
	private static DataInputStream dStream;
	
	public BinaryReaderJ(File file){
		this.file = file;
		try {
			in = new FileInputStream(file);
			dStream = new DataInputStream(in);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 读取一个byte
	 * @author RKGG
	 * @param 返回int
	 * */
	public static int read(){
		int b = 0;
		try {
			b = dStream.read();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return b;
	}
	
	/**
	 * 一次性读取 length长度
	 * 返回长度为length的byte[]
	 * @author RKGG 
	 * @param length 长度
	 * @return 返回byte[]
	 * */
	public static byte[] read(int length){
		byte[] bs = new byte[length];
		byte[] rs = new byte[length];
		try {
			dStream.read(bs,0,length);
			System.arraycopy(bs, 0, rs, 0, length);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return rs;
	}
	
	/**
	 * 读取2byte 返回1个int
	 * @author RKGG
	 * @return int
	 * */
	public static int readInt16(){
		byte[] bs = new byte[2];
		int temp = 0;
		try {
			dStream.read(bs,0,2);
			temp = HexUtil.byte2int(bs);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return temp;
	}
	
	/**
	 * 读取4byte 返回1个int
	 * @author RKGG
	 * @return 返回int
	 * */
	public static int readInt32(){
		byte[] bs = new byte[4];
		int temp = 0;
		try {
			dStream.read(bs,0,4);
			temp = HexUtil.byteArrayToInt(bs, 0);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return temp;
	}

	/**
	 * 将一个byte[] 按索引位置读取2byte 返回Int
	 * @author RKGG
	 * @param byte[]
	 * @param 起始位置
	 * @return int
	 * */
	public static int ToInt16(byte[] b,int start){
		byte[] bs = new byte[2];
		int temp = 0;
		System.arraycopy(b, start, bs, 0, 2);
		temp = HexUtil.byte2int(bs);
		return temp;
	}
	
	/**
	 * 将一个byte[] 按索引位置读取4byte 返回Int
	 * @author RKGG
	 * @param byte[]
	 * @param 起始位置
	 * @return int
	 * */
	public static int ToInt32(byte[] b,int start){
		byte[] bs = new byte[4];
		int temp = 0;
		System.arraycopy(b, start, bs, 0, 4);
		temp = HexUtil.byteArrayToInt(bs, 0);
		return temp;
	}
	
	/**
	 * 读取8byte 返回1个double
	 * @author RKGG
	 * @return double
	 * */
	public static double readDouble(){
		byte[] bs = new byte[8];
		double b = 0;
		try {
			dStream.read(bs,0,8);
			b = HexUtil.byteArrayToDouble(bs, 0);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return b;
	}
	
	/**
	 * 将一个byte[] 按索引位置读取8byte 返回Double
	 * @author RKGG
	 * @param byte[]
	 * @param 起始位置
	 * @return double
	 * */
	public static double ToDouble(byte[] b,int start){
		byte[] bs = new byte[8];
		System.arraycopy(b, start, bs, 0, 8);
		double d = HexUtil.byteArrayToDouble(bs, 0);
		return d;
	}
	
	/**
	 * 读取一个长度为 length*8 的byte[]
	 * 返回一个长度为 length的double[]
	 * @author RKGG
	 * @param length 长度
	 * @param 返回double[]
	 * */
	public static double[] readDoubles(int length){
		byte[] bs = new byte[length*8];
		double[] d = new double[length];
		try {
			dStream.read(bs,0,bs.length);
			d = HexUtil.getData(bs, 0);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return d;
	}
	
	/**
	 * 读取4byte 返回1个float
	 * @author RKGG
	 * @return 返回float
	 * */
	public static float readFloat(){
		byte[] bs = new byte[4];
		float f = 0;
		try {
			dStream.read(bs,0,4);
			f = HexUtil.byteArrayToFloat(bs, 0, 0);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return f;
	}
	
	/**
	 * 将一个byte[] 按索引位置读取4byte返回 1个float
	 * @author RKGG
	 * @param byte[]
	 * @param 起始位置
	 * @return 返回float
	 * */
	public static float ToFloat(byte[] b,int start){
		byte[] bs = new byte[4];
		System.arraycopy(b, start, bs, 0, 4);
		float f = HexUtil.byteArrayToFloat(bs, 0, 0);
		return f;
	}
	
	/**
	 * 读取一个长度为 length*4 的byte[]
	 * 返回一个长度为 length的float[] 
	 * @author RKGG
	 * @param length
	 * @return float[]
	 * */
    public static float[] readFloats(int length){
    	byte[] bs = new byte[length*4];
    	float[] fs = new float[length];
    	try {
			dStream.read(bs,0,bs.length);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        String s = new String(bs);
        String[] ssr = s.split(",");
        for (int i = 0; i < fs.length; i++) {
            fs[i] = Float.parseFloat(ssr[i]);
        }
        return fs;
    }
    
	/**
	 * 读取1byte转1char
	 * @author RKGG
	 * @return char
	 * */
	public static char readChar(){
		byte[] bs = new byte[1];
		char ch = 0;
		try {
			dStream.read(bs,0,1);
			ch = HexUtil.byteArrayToChar(bs);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ch;	
	}
	
	/**
	 * 读取长度为length的byte[]
	 * 返回长度为length的char[]
	 * @author RKGG
	 * @param length 
	 * @return char[]
	 * */
	public static char[] readChars(int length){
		byte[] bs = new byte[length];
		char[] ch = new char[length];
		try {
			dStream.read(bs,0,bs.length);
			ch = HexUtil.getChars(bs);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ch;
	}
	
	
	/**
	 * 读取一定长度 l的byte[]
	 * 返回长度为 l的String
	 * @author RKGG
	 * @param length
	 * @return String
	 * */
	public static String readString(int length){
		byte[] bs = new byte[length];
		String string = "";
		try {
			dStream.read(bs,0,bs.length);
			string = new String(bs);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return string;
	}
	
	
	/**
	 * 读取日期格式的double
	 * 返回日期格式
	 * @author RKGG
	 * @param format
	 * @return String
	 * */
	public static String readDate(String format){
		byte[] bs = new byte[8];
		String time = "";
		double time_d = 0;
		try {
			dStream.read(bs,0,8);
			time_d = HexUtil.byteArrayToDouble(bs, 0);
			time = HexUtil.doubleToDate(time_d, format);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return time;
	}
	
	/**
	 * 读取4byte转1boolean
	 * @author RKGG
	 * @param byte[]
	 * @param start
	 * @return boolean
	 * */
	public static boolean ToBoolean(byte[] b,int start){
		byte[] bs = new byte[4];
		System.arraycopy(b, start, bs, 0, 4);
		boolean tmp = HexUtil.byteArrayToBoolean(bs, 0);
		return tmp;
	}
	
	/**
	 * 关流
	 * @author RKGG
	 * */
	public static void close(){
		try {
			dStream.close();
			in.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
HexUtil类如下:

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.xml.transform.Templates;

public class HexUtil {

	/**
	 * 4byte 转 int
	 * */
	public static int byteArrayToInt(byte[] b, int start) {
		int value = 0;
		byte[] temp = null;
		temp = new byte[4];
		System.arraycopy(b, start, temp, 0, 4);
		value = byte2int(temp);
		return value;
	}

	public static int byteToInt(byte[] b, int offset) {
		int value = 0;
		for (int i = 0; i < 4; i++) {
			int shift = (4 - 1 - i) * 8;
			value += (b[i + offset] & 0x000000FF) << shift;
		}
		return value;
	}

	/**
	 * 2byte 转int
	 * */
	public static int byte2int(byte[] res) {
		int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00);
		return targets;
	}

	/**
	 * byte[] 转 boolean
	 * */
	public static boolean byteArrayToBoolean(byte[] data, int start) {
		if (data == null || data.length < 4) {
			return false;
		}
		byte[] bytes = new byte[4];
		System.arraycopy(data, start, bytes, 0, 4);
		int tmp = byteArrayToInt(bytes, 0);
		return (tmp == 0) ? false : true;
	}

	/**
	 * get double[]
	 * */
	public static double[] getData(byte[] bs, int start) {
		byte[] data;
		double[] yData = new double[bs.length / 8];
		int counts = 0;
		for (int i = start; i < bs.length - 1;) {
			data = new byte[8];
			System.arraycopy(bs, i, data, 0, 8);
			yData[counts] = byteArrayToDouble(data, 0);
			i += 8;
			counts++;
		}
		return yData;
	}

	public static double byteArrayToDouble(byte[] b, int start) {
		long l;
		byte[] bytes = new byte[8];
		System.arraycopy(b, start, bytes, 0, 8);
		l = bytes[0];
		l &= 0xff;
		l |= ((long) bytes[1] << 8);
		l &= 0xffff;
		l |= ((long) bytes[2] << 16);
		l &= 0xffffff;
		l |= ((long) bytes[3] << 24);
		l &= 0xffffffffl;
		l |= ((long) bytes[4] << 32);
		l &= 0xffffffffffl;
		l |= ((long) bytes[5] << 40);
		l &= 0xffffffffffffl;
		l |= ((long) bytes[6] << 48);
		l &= 0xffffffffffffffl;
		l |= ((long) bytes[7] << 56);
		return Double.longBitsToDouble(l);
	}

	/**
	 * byte[] 转string
	 * 
	 * */
	public static String byteTostring(byte[] bs) {
		String s = "";
		try {
			s = new String(bs,"GB2312");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return s;
	}

	/**
	 * byte[] 转float
	 * */
	public static float byteArrayToFloat(byte[] b, int index, int start) {
		int l;
		byte[] data = new byte[4];
		System.arraycopy(b, start, data, 0, 4);
		l = data[index + 0];
		l &= 0xff;
		l |= ((long) data[index + 1] << 8);
		l &= 0xffff;
		l |= ((long) data[index + 2] << 16);
		l &= 0xffffff;
		l |= ((long) data[index + 3] << 24);
		return Float.intBitsToFloat(l);
	}

	/**
	 * byte[] 转 char
	 * */
	public static char[] getChar(byte[] bytes, int start) {
		byte[] data;
		char[] data_char = new char[bytes.length / 2];
		int counts = 0;
		for (int i = start; i < bytes.length - 1;) {
			data = new byte[2];
			System.arraycopy(bytes, i, data, 0, 2);
			data_char[counts] = byteArrayToChar(data);
			i += 2;
			counts++;
		}
		return data_char;
	}

	public static char byteArrayToChar(byte[] b) {
		char c = (char) (((b[0] & 0xFF) << 8) | (b[1] & 0xFF));
		return c;
	}

	public static char[] getChars(byte[] bytes) {
		Charset cs = Charset.forName("UTF-8");
		ByteBuffer bb = ByteBuffer.allocate(bytes.length);
		bb.put(bytes);
		bb.flip();
		CharBuffer cb = cs.decode(bb);

		return cb.array();
	}

	/**
	 * double 转 date
	 * */
	public static String doubleToDate(Double d,String format) {
		String t;
		Calendar base = Calendar.getInstance();
		SimpleDateFormat outFormat = new SimpleDateFormat(format);
		// Delphi的日期类型从1899-12-30开始
		base.set(1899, 11, 30, 0, 0, 0);
		base.add(Calendar.DATE, d.intValue());
		base.add(Calendar.MILLISECOND, (int) ((d % 1) * 24 * 60 * 60 * 1000));
		t = outFormat.format(base.getTime());
		return t;
	}
}

以上就是仿BinaryReader的Java代码,欢迎大家提出问题与批评指正。



猜你喜欢

转载自blog.csdn.net/xiaoxun2802/article/details/78898617