仿C# BinaryReader 读取二进制文件的Java实现代码
2017-12-26 09:04
417 查看
最近手头的活儿暂告一段落,正好有时间整理一下前面做的一个项目,在某些时候,我们需要读取一个格式明确的二进制文件,由于格式确定,我们还需要按照位数来读取相对应的内容(例如,我们需要读取第44位到第56位的这12个字节),说到这儿,很多人大概都会说,这有什么难的,Java读取二进制的方法有一大堆,随便找一个都可以读取,的确,Java的读取方法有很多,但是似乎没有一个读取一个字节就会让当前字节位提升一位的方法,如果你需要按照某个字节来读取,就会出现问题(当然,如果利用复制数组来“曲线救国”,那就另当别论)。
由于C#里的 BinaryReader 其中包含的很多读取二进制的方法都不错,关键是都会自动提升位数,所以就仿着写了一个可以自动提升的工具类BinaryReaderJ,废话不多说,直接上代码:
以上就是仿BinaryReader的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); ret b697 urn (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代码,欢迎大家提出问题与批评指正。
相关文章推荐
- 实现高效的数据库连接池(附带完整代码C#和Java实现)(转)
- C#.NET示例读写xml所有节点的代码实现方法和读取xml节点的数据总结
- [ZT]C# 代码实现设置用户"NETWORK SERVICE"具有对文件夹的读取权限。
- ADO.NET 读取EXCEL的实现代码((c#))
- 实现高效的数据库连接池(附带完整代码C#和Java实现)
- javascript实现的像java、c#之类的sleep暂停的函数代码
- C#.NET示例读写xml所有节点的代码实现方法和读取xml节点的数据总结
- Java 通过 BufferReader 实现 文件 写入读取 示例
- C#用Activex实现Web客户端读取RFID功能的代码
- C# 创建文本文件写入读取实现代码
- C#DES加密,JavaDES解密,另转C#和Java实现Des完整代码
- 实现高效的数据库连接池(附带完整代码C#和Java实现)
- java代码-----实现有键盘获得的字符串存储在文件中,并从文件中读取后显示在屏幕上
- 如何编写出高效的数据库连接池(附带完整代码C#和Java实现)
- 在C#中实现用XmlReader读取Excel 2007的文件
- 如何编写出高效的数据库连接池(附带完整代码C#和Java实现)
- C#读取TXT文件的代码实现
- 如何编写出高效的数据库连接池(附带完整代码C#和Java实现) .
- C#读取TXT文件的代码实现
- 如何编写出高效的数据库连接池(附带完整代码C#和Java实现)