当字符位于字符串的开头和结尾时,如何将二进制数据拆分为十六进制字符串

时间:2014-10-13 10:33:46

标签: java

我想基于字符值分割数据,这是两个右括号))作为子字符串的开头,回车符CR作为子字符串的结尾。数据以字节的形式存在,如何分割它。到目前为止,我已经提出了这个问题。

    public class ByteDecoder {

         public static void main(String[] args) throws IOException {

              InputStream is = null;
              DataInputStream dis = null;
             try{
                 is = new FileInputStream("byte.log");
                 dis = new DataInputStream(is);
                 int count = is.available();
                 byte[] bs = new byte[count];
                 dis.read(bs);
                 for (byte b:bs)
                  {
                     char c = (char)b;
                     System.out.println(c);
                  //convert bytes to hex string
                  // String c = DatatypeConverter.printHexBinary( bs);
                  }
                  }catch(Exception e){
                    e.printStackTrace();
                     }finally{
                         if(is!=null)
                         is.close();
                         if(dis!=null)
                         dis.close();
          }   
      }
}

1 个答案:

答案 0 :(得分:0)

CR(不幸的是13)作为二进制数据的结束标记可能有点危险。更危险的是如何写入文本和字节:文本必须以某种编码形式写为字节。

但考虑到这一点,可以将FileInputStream包装在你自己的ByteLogInputStream中,并保持读取状态:

/**
 * An InputStream converting bytes between ASCII "))" and CR to hexadecimal.
 * Typically wrapped as:
 * <pre>
 * try (BufferedReader in = new BufferedReader(
 *         new InputStreamReader(
 *             new ByteLogInputStream(
 *                 new FileInputStream(file), "UTF-8"))) {
 *     ...
 * }
 * </pre>
 */
public class ByteLogInputStream extends InputStream {

    private enum State {
        TEXT,
        AFTER_RIGHT_PARENT,
        BINARY
    }

    private final InputStream in;
    private State state = State.TEXT;
    private int nextHexDigit = 0;

    public ByteLogInputStream(InputStream in) {
        this.in = in;
    }

    @Override
    public int read() throws IOException {
        if (nextHexDigit != 0) {
            int hex = nextHexDigit;
            nextHexDigit = 0;
            return hex;
        }
        int ch = in.read();
        if (ch != -1) {
            switch (state) {
                case TEXT:
                    if (ch == ')') {
                        state = State.AFTER_RIGHT_PARENT;
                    }
                    break;
                case AFTER_RIGHT_PARENT:
                    if (ch == ')') {
                        state = State.BINARY;
                    }
                    break;
                case BINARY:
                    if (ch == '\r') {
                        state = State.TEXT;
                    } else {
                        String hex2 = String.format("%02X", ch);
                        ch = hex2.charAt(0);
                        nextHexDigit = hex2.charAt(1);
                    }
                    break;
            }
        }
        return ch;
    }
}

由于一个二进制字节产生两个十六进制数字,因此需要为下一个数字缓冲nextHexDigit。

我没有覆盖可用(考虑到可能的nextHexDigit)。

如果要检查\r\n是否跟随,则应使用PushBackReader。我没有使用InputStream,因为你没有指定编码。