如题,在java中,如何按照bit位来读取数据呢?
对于字节(byte),可以使用ByteInputStream来读;
那么对于位(bit)呢?
现在的需求是:
① 从文件固定位置读取8bit,判断它是不是特定的一串二进制码(例如01110111),如果是,转到②;如果不是,转到③;
② 将后面的64bit数据按照ASCII码读取,然后回到①;
③ 移动1bit位,回到①。
------解决方案--------------------
------解决方案--------------------
Java中byte的长度是定的,现根据byte的长度算到要取bit的byte的位置,然后先把byte取出来,然后用“&”“|”“^”等几个位操作符来操作byte,这几个操作符怎么用具体查一下
------解决方案--------------------
看LZ的意思,00011101110000111100001110这个串应该是保存在byte数组中的
API估计是没有了,自己写程序循环控制吧
给LZ一段例子代码,LZ参考着修改吧
- Java code
import java.util.*;public class Test { public static void main(String[] args) throws Throwable { byte[] data = new byte[12]; //测试数据准备,假设LZ所说的串是保存在byte数组中 data[0] = Integer.valueOf("00011101", 2).byteValue(); //头3个数据用LZ的例子数据 data[1] = Integer.valueOf("11000011", 2).byteValue(); data[2] = Integer.valueOf("11000011", 2).byteValue(); for (int i=3; i<data.length; i++) { //有规律的数据方便检验程序的正确性 data[i] = (i%2 == 0) ? (byte)0x00 : (byte)0xff; } System.out.println("test data:"); //测试数据打印 for (int i=0; i<data.length; i++) { System.out.printf("%s ", bitString((byte)data[i])); } System.out.println(); byte key = Integer.valueOf("01110111", 2).byteValue(); //在bit数据中找到的key System.out.println("key:"); System.out.printf("key=%s\n", bitString(key)); //为了检验程序,程序中对于每次移位以及取数据后做了打印处理 System.out.println("--------test start--------"); //测试开始 byte b = 0; for (int i=0, bit=0; i<data.length; i++) { if (i == 0) { b = data[i]; //第一个数据直接取byte的值 } else { System.out.printf("before bit offset:b=%s\n", bitString(b)); if (bit > 0) { //如果发生移位,并且不是移动整个byte的时候 b <<= bit; //取下一个byte前bit位来弥补上一个byte不足的数据 b |= (data[i] >> (8-bit)) & (0x00ff >> (8-bit)); System.out.printf("%d bit offset:b=%s\n", bit, bitString(b)); if (b == key) break; } for (int j=bit; j<8; j++) { //从下一个数据的bit位开始循环 b <<= 1; //上次数据左移1位 b |= ((data[i] >> (8-j-1)) & 1); //用下一个数据的1位来补到上次数据的后1位 System.out.printf("1 bit offset:b=%s\n", bitString(b)); if (b == key) { //如果找到key,则退出循环,并保存移动的bit数 bit = (j+1)%8; break; } if (j == 7 && bit > 0) bit = 0; } } if (b == key) { //如果找到key System.out.printf("find key=%s\n", bitString(b)); char[] c = new char[4]; //取64位信息保存到字符数组中 for (int j=i, k=0, cnt=0; j<i+9 && j<data.length; j++) { //从当前的byte开始循环8个byte取64位数据 if (j==i) { b = data[j]; //第一个byte数据直接保存 } else { if (bit > 0) { //如果发生了移位,即不是整byte的时候 b <<= bit; //上一个byte左移bit位 b |= (data[j] >> (8-bit)) & (0x00ff >> (8-bit)); //用下一个的前bit位补到上一个数据的后bit位 } if (cnt == 0) { //第一个byte的时候 c[k] = (char)b; //保存到字符数组中,并让字符左移8位,相当于字符的高8位保存 c[k] <<= 8; cnt++; } else if (cnt == 1) { //第二个byte的时候,保存字符的低8位 c[k] |= b; k++; cnt = 0; } b = data[j]; } } for (int j=0; j<c.length; j++) { //打印64 bit的结果 System.out.printf("char data = %s\n", bitString(c[j])); } i += 8; if (i < data.length) b = data[i]; } } System.out.println("--------test end--------"); } public static String bitString(byte b) { //获取byte的二进制信息 StringBuilder buf = new StringBuilder(Integer.toBinaryString(b & 0x000000ff)); while (buf.length() < 8) { buf.insert(0, "0"); } return buf.toString(); } public static String bitString(char c) {//获取char的二进制信息 StringBuilder buf = new StringBuilder(Integer.toBinaryString(c & 0x0000ffff)); while (buf.length() < 16) { buf.insert(0, "0"); } return buf.toString(); }}/*简单测试了一下,结果如下test data:00011101 11000011 11000011 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111key:key=01110111--------test start--------before bit offset:b=000111011 bit offset:b=001110111 bit offset:b=01110111find key=01110111char data = 0000111100001111char data = 1111110000000011char data = 1111110000000011char data = 1111110000000011before bit offset:b=111111112 bit offset:b=111111001 bit offset:b=111110001 bit offset:b=111100001 bit offset:b=111000001 bit offset:b=110000001 bit offset:b=100000001 bit offset:b=00000000before bit offset:b=000000001 bit offset:b=000000011 bit offset:b=000000111 bit offset:b=000001111 bit offset:b=000011111 bit offset:b=000111111 bit offset:b=001111111 bit offset:b=011111111 bit offset:b=11111111--------test end--------*/