如题,在java中,如何按照bit位来读取数据呢?
对于字节(byte),可以使用ByteInputStream来读;
那么对于位(bit)呢?现在的需求是:
① 从文件固定位置读取8bit,判断它是不是特定的一串二进制码(例如01110111),如果是,转到②;如果不是,转到③;② 将后面的64bit数据按照ASCII码读取,然后回到①;③  移动1bit位,回到①。

解决方案 »

  1.   

    能讀byte就相當於能讀bit了,繼續分解嘛
    貌似沒見過直接讀bit的
      

  2.   

    感谢2、3楼的回答。能详细一点吗?
    例如一串二进制码为00011101110000111100001110……
    我要找到01110111,然后提取后面的64bit。
    如果用byte来读,读到的是00011101,这个不是要找的,跳过一位之后就到了11000011了,也不是。但事实上跳过2bit,从第3bit到第10bit,它刚好就是01110111,因此需要读第11bit~75bit就对啦~~
      

  3.   

    例如一串二进制码为00011101110000111100001110……
    这个串是字符串还是什么?数据是从哪里来的?你是如何用byte读取?
    先把你的问题描述清楚再说
      

  4.   

    如果沒找到直接讀bit的方法,那就自己處理
    讀完所需的bytes,將其轉譯成bits,再進行你的業務邏輯處理
      

  5.   

    回6L:您是说这样子吗?……
    BufferedInputStream bis = new BufferedInputStream(fis);
    byte [] b = new byte[100];
    bis.read(b,0,100);
    StringBuffer sb = new StrigBuffer("");
    for(int i=0;i<b.length;i++) sb.append(Integer.toBinaryString(b[i]));String sall = sb.toString();
    //
    int seek = sall.indexOf("01110111");
    ……
    这样可以找到所在的位置,可以提取后面的64bit呢?好像又是一个麻烦事。。而且转换成字符串操作,好像不太科学吧?
      

  6.   

    Java中byte的长度是定的,现根据byte的长度算到要取bit的byte的位置,然后先把byte取出来,然后用“&”“|”“^”等几个位操作符来操作byte,这几个操作符怎么用具体查一下
      

  7.   

    java里要怎樣科學地表示bit數據呢?boolean數組?貌似也要占一個字節,而不是它實際所用信息量的一個bit,那麼就等效于byte數組
    而String操作方便,表示也更直觀,也抵消了它更占空間的劣勢了。這也是爲什麽jdk最容易想到的轉bit api是toBinaryString了(除非有直接操作位數據的api)。Short answer: yes, boolean values are manipulated as 32-bit entities, but arrays of booleans use 1 byte per element.Longer answer: the JVM uses a 32-bit stack cell, used to hold local variables, method arguments, and expression values. Primitives that are smaller than 1 cell are padded out, primitives larger than 32 bits (long and double) take 2 cells. This technique minimizes the number of opcodes, but does have some peculiar side-effects (such as the need to mask bytes).Primitives stored in arrays may use less than 32 bits, and there are different opcodes to load and store primitive values from an array. Boolean and byte values both use the baload and bastore opcodes, which implies that boolean arrays take 1 byte per element.As far as in-memory object layout goes, this is covered under the "private implementation" rules, it can be 1 bit, 1 byte, or as another poster noted, aligned to a 64-bit double-word boundary. Most likely, it takes the basic word size of the underlying hardware (32 or 64 bits).
    http://stackoverflow.com/questions/1907318/java-boolean-primitive-type-size
      

  8.   

    看LZ的意思,00011101110000111100001110这个串应该是保存在byte数组中的
    API估计是没有了,自己写程序循环控制吧
    给LZ一段例子代码,LZ参考着修改吧
    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 11111111
    key:
    key=01110111
    --------test start--------
    before bit offset:b=00011101
    1 bit offset:b=00111011
    1 bit offset:b=01110111
    find key=01110111
    char data = 0000111100001111
    char data = 1111110000000011
    char data = 1111110000000011
    char data = 1111110000000011
    before bit offset:b=11111111
    2 bit offset:b=11111100
    1 bit offset:b=11111000
    1 bit offset:b=11110000
    1 bit offset:b=11100000
    1 bit offset:b=11000000
    1 bit offset:b=10000000
    1 bit offset:b=00000000
    before bit offset:b=00000000
    1 bit offset:b=00000001
    1 bit offset:b=00000011
    1 bit offset:b=00000111
    1 bit offset:b=00001111
    1 bit offset:b=00011111
    1 bit offset:b=00111111
    1 bit offset:b=01111111
    1 bit offset:b=11111111
    --------test end--------
    */
      

  9.   

    拿出后面1byte,用位运算计算,如果得到正确的结果,再拿出后面的64bit,转换成 ASCII 存起来。
      

  10.   

    非常谢谢12L,你的思路很棒。就是读取按照byte来读,只是查找应该取前、后两个byte b1、b2,通过移位和或操作来实现。
    …………
    //读取到的数据
    byte [] b = bis.read();
    // 01110111的10进制表示
    byte search = 119;
    int seek,position;
    byte temp;
    for(int i = 0;i<b.length;i++){
    for(int j = 0; j < 7 ;j++) {
        temp = (byte) ((b[i]<<j) | (b[i+1]>>j));
        if(temp == search){
          seek = i;
          position = j;
          return true;
        }
    }
    }
    ………………
      

  11.   

    最开始考虑这个问题,思路局限,总想着按bit读取,然后构造出byte,再和关键字去比较。。见笑了额……