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

Best way to parse data stream containing of pairs of id and data point

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

我的数据流遵循以下格式:

ID(4 字节)数据(8 字节)ID(4 字节)数据(8 字节)

每个数据框有 6 对 id 和数据。

解析此类流的最佳做法是什么?我希望能够过滤掉 id 和一些数据,这样我就会有一个 table 只有 DATA01、DATA02 等

如何在第一个 ID(例如 000,整数)之后提取第一个数据点(长),然后在第二个 ID(001,整​​数)之后提取第二个数据点(双精度)。

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

在此先感谢您的问候,

菲利普

请提供一些示例代码!


我猜你有一些 ByteArrayInputStream?看看 API: https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayInputStream.html

您可以简单地使用 read(...) 方法来达到您的目的:https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayInputStream.html#read(byte[],%20int,%20int)


这样你就可以做这样的事情:

ByteArrayInputStream in;

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

byte[] data = new byte[8];
in.read(data, 0, 8);

只需将其放入一个循环中即可。

如果 read(...) 方法 returns -1,则流已完成。如果 read(...) 方法 return 比您预期的 return.

少,您还可以检查错误

很难说出你真正想要达到的目标。

可能会假设您需要这样的答案:

public Map<Integer, Double> read(InputStream stream);

尝试这样的事情:

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]);
}

ByteBuffer 非常适合 class 来完成您想要做的事情。 ByteBuffer 允许您直接将字节数组转换为它们对应的原始值。这与一次读入缓冲区而不是一个字节相结合,您将拥有一个相对简洁高效的解决方案!

示例:

    public void parseStream( InputStream is ) throws IOException 
    {
        boolean vtoggle = true; // Are we converting to long or double?
        ByteBuffer idBuffer = ByteBuffer.allocate( 4 ); // Initialize our id buffer
        ByteBuffer valueBuffer = ByteBuffer.allocate( 8 ); // Initialize our value buffer

        while( true /*or some real condition*/ )
        {
            idBuffer.put( readFromInput( is, 4 ) ); // Store the id bytes
            valueBuffer.put( readFromInput( is, 8 ) ); // Store the value bytes
            int id = idBuffer.getInt(); // Convert id bytes
            if( vtoggle )
            {
                long lvalue = valueBuffer.getLong(); // Convert long bytes
                // Do something with value
            }
            else
            {
                double dvalue = valueBuffer.getDouble(); // Convert double bytes
                // Do something with value
            }
            idBuffer.clear(); // Reset id buffer
            valueBuffer.clear(); // Reset value buffer
            vtoggle = !vtoggle; // Code to alternate whether or not we are converting to long or double
        }
    }

    /**
     * Read and return a certain number of bytes from our stream
     */
    public byte[] readFromInput( InputStream is, int count ) throws IOException
    {
        byte[] buffer = new byte[ count ];
        int bytesRead = 0;
        int offset = 0;
        while( ( bytesRead = is.read( buffer, offset, buffer.length - offset  ) ) > 0 )
        {
            offset += bytesRead;
        }
        if( offset == buffer.length )
        {
            return buffer;
        }
        else
        {
            throw new IOException( "Unexpected end to stream." );
        }
    }

这显然只是一个模板,但希望它能指导您正确解决问题。

尝试 preon. See this link 举个简单的例子。

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