Java 解析包含id和数据点对的数据流的最佳方法

Java 解析包含id和数据点对的数据流的最佳方法,java,parsing,stream,byte,pipes-filters,Java,Parsing,Stream,Byte,Pipes Filters,我正在尝试编写一个简单的管道和过滤器系统,目前我正在一次解析一个字节的输入流 我的数据流采用以下格式: ID(4字节)数据(8字节)ID(4字节)数据(8字节) 每个数据帧有6对ID和数据 解析这样一个流的最佳实践是什么?我希望能够过滤掉ID和一些数据,这样我将有一个只包含DATA01、DATA02等的表 例如,如何提取第一个id(000,例如整数)之后的第一个数据点(long),然后提取第二个id(001,整数)之后的第二个数据点(double) 我希望我能详细说明我的问题 提前感谢并问候您

我正在尝试编写一个简单的管道和过滤器系统,目前我正在一次解析一个字节的输入流

我的数据流采用以下格式:

ID(4字节)数据(8字节)ID(4字节)数据(8字节) 每个数据帧有6对ID和数据

解析这样一个流的最佳实践是什么?我希望能够过滤掉ID和一些数据,这样我将有一个只包含DATA01、DATA02等的表

例如,如何提取第一个id(000,例如整数)之后的第一个数据点(long),然后提取第二个id(001,整数)之后的第二个数据点(double)

我希望我能详细说明我的问题

提前感谢并问候您


飞利浦

请提供一些示例代码


我猜你有一些
ByteArrayInputStream
?请看一下API:

您可以简单地使用
read(…)
方法:


通过这种方式,您可以执行以下操作:

ByteArrayInputStream in;

byte[] id = new byte[4];
in.read(id, 0, 4);

byte[] data = new byte[8];
in.read(data, 0, 8);
public static void main(String[] args) throws IOException {
    InputStream stream = ...;
    byte[] buffer = new byte[12];
    Map<Integer, Double> values = new HashMap<>();
    while (stream.read(buffer) == 12) { // Could it read all data?
        int id = readInt(buffer, 0);
        double value = readDouble(buffer, 4);
        values.put(id, value);
    }
// use values
}

public static double readDouble(byte[] data, int offset) {
    return Double.longBitsToDouble(readLong(data, offset));
}

public static long readLong(byte[] data, int offset) {
    // Do some bit shifting to adjust the numbers.
    return (((long) readInt(data, offset)) << 32) + readInt(data, offset + 4);
}

public static int readInt(byte[] data, int offset) {
    return (data[offset + 0] << 24) + (data[offset + 1] << 16) + (data[offset + 2] << 8) + (data[offset + 3]);
}
只要把它放进一个循环,你就完成了


如果
read(…)
方法返回
-1
,则流结束。如果
read(…)
方法返回的值小于预期值,您还可以检查错误。

请提供一些示例代码


我猜你有一些
ByteArrayInputStream
?请看一下API:

您可以简单地使用
read(…)
方法:


通过这种方式,您可以执行以下操作:

ByteArrayInputStream in;

byte[] id = new byte[4];
in.read(id, 0, 4);

byte[] data = new byte[8];
in.read(data, 0, 8);
public static void main(String[] args) throws IOException {
    InputStream stream = ...;
    byte[] buffer = new byte[12];
    Map<Integer, Double> values = new HashMap<>();
    while (stream.read(buffer) == 12) { // Could it read all data?
        int id = readInt(buffer, 0);
        double value = readDouble(buffer, 4);
        values.put(id, value);
    }
// use values
}

public static double readDouble(byte[] data, int offset) {
    return Double.longBitsToDouble(readLong(data, offset));
}

public static long readLong(byte[] data, int offset) {
    // Do some bit shifting to adjust the numbers.
    return (((long) readInt(data, offset)) << 32) + readInt(data, offset + 4);
}

public static int readInt(byte[] data, int offset) {
    return (data[offset + 0] << 24) + (data[offset + 1] << 16) + (data[offset + 2] << 8) + (data[offset + 3]);
}
只要把它放进一个循环,你就完成了


如果
read(…)
方法返回
-1
,则流结束。如果
read(…)
方法返回的值小于您预期的值,您还可以检查错误。

很难判断您实际想要实现什么

我的回答是你需要这样的东西:

public Map<Integer, Double> read(InputStream stream);
公共地图读取(InputStream);
试着这样做:

ByteArrayInputStream in;

byte[] id = new byte[4];
in.read(id, 0, 4);

byte[] data = new byte[8];
in.read(data, 0, 8);
public static void main(String[] args) throws IOException {
    InputStream stream = ...;
    byte[] buffer = new byte[12];
    Map<Integer, Double> values = new HashMap<>();
    while (stream.read(buffer) == 12) { // Could it read all data?
        int id = readInt(buffer, 0);
        double value = readDouble(buffer, 4);
        values.put(id, value);
    }
// use values
}

public static double readDouble(byte[] data, int offset) {
    return Double.longBitsToDouble(readLong(data, offset));
}

public static long readLong(byte[] data, int offset) {
    // Do some bit shifting to adjust the numbers.
    return (((long) readInt(data, offset)) << 32) + readInt(data, offset + 4);
}

public static int readInt(byte[] data, int offset) {
    return (data[offset + 0] << 24) + (data[offset + 1] << 16) + (data[offset + 2] << 8) + (data[offset + 3]);
}
publicstaticvoidmain(字符串[]args)引发IOException{
InputStream流=。。。;
字节[]缓冲区=新字节[12];
映射值=新的HashMap();
而(stream.read(buffer)==12){//它能读取所有数据吗?
int id=readInt(缓冲区,0);
double value=readDouble(缓冲区,4);
value.put(id,value);
}
//使用值
}
公共静态双读双写(字节[]数据,整数偏移){
返回Double.longBitsToDouble(readLong(数据,偏移量));
}
公共静态long readLong(字节[]数据,int偏移量){
//做一些移位来调整数字。

return(((long)readInt(data,offset))很难判断您实际想要实现什么

我的回答是你需要这样的东西:

public Map<Integer, Double> read(InputStream stream);
公共地图读取(InputStream);
试着这样做:

ByteArrayInputStream in;

byte[] id = new byte[4];
in.read(id, 0, 4);

byte[] data = new byte[8];
in.read(data, 0, 8);
public static void main(String[] args) throws IOException {
    InputStream stream = ...;
    byte[] buffer = new byte[12];
    Map<Integer, Double> values = new HashMap<>();
    while (stream.read(buffer) == 12) { // Could it read all data?
        int id = readInt(buffer, 0);
        double value = readDouble(buffer, 4);
        values.put(id, value);
    }
// use values
}

public static double readDouble(byte[] data, int offset) {
    return Double.longBitsToDouble(readLong(data, offset));
}

public static long readLong(byte[] data, int offset) {
    // Do some bit shifting to adjust the numbers.
    return (((long) readInt(data, offset)) << 32) + readInt(data, offset + 4);
}

public static int readInt(byte[] data, int offset) {
    return (data[offset + 0] << 24) + (data[offset + 1] << 16) + (data[offset + 2] << 8) + (data[offset + 3]);
}
publicstaticvoidmain(字符串[]args)引发IOException{
InputStream流=。。。;
字节[]缓冲区=新字节[12];
映射值=新的HashMap();
而(stream.read(buffer)==12){//它能读取所有数据吗?
int id=readInt(缓冲区,0);
double value=readDouble(缓冲区,4);
value.put(id,value);
}
//使用值
}
公共静态双读双写(字节[]数据,整数偏移){
返回Double.longBitsToDouble(readLong(数据,偏移量));
}
公共静态long readLong(字节[]数据,int偏移量){
//做一些移位来调整数字。
return(((long)readInt(data,offset))是一个很好的类,用于完成您尝试执行的操作。ByteBuffer允许您直接将字节数组转换为其相应的基本值。这与每次读取一个字节而不是一个字节相结合,您将获得一个相对简洁高效的解决方案

例如:

这显然只是一个模板,但希望它能引导您找到问题的正确解决方案。

是一个很好的类,可以完成您正在尝试做的事情。ByteBuffer允许您直接将字节数组转换为相应的基元值。这与读取缓冲区(而不是一次读取一个字节)相结合,您将拥有一个相对简洁高效的解决方案

例如:

这显然只是一个模板,但希望它能引导您找到问题的正确解决方案。

尝试一下。请参阅下面的简单示例

如果您不想使用库,那么DataInputStream很适合您的用例。请参阅此示例。

尝试。请参阅此示例以获取简单示例


如果您不想使用库,那么DataInputStream很适合您的用例。请参阅此示例。

谢谢!这就是我想要的。我不知道如何根据ID“拆分”传入流。太好了!谢谢!这就是我想要的。我不知道如何“拆分”根据ID输入的流。完美!谢谢!这就是我想要做的!完美。@Ipsider这就是你最终使用的吗?如果是,我希望你接受我的答案:)谢谢!这就是我想要做的!完美。@Ipsider这就是你最终使用的吗?如果是,我希望你接受我的答案:)非常感谢你的评论。我会尝试一下。非常感谢你的评论。我会尝试一下。