Java 解析包含id和数据点对的数据流的最佳方法
我正在尝试编写一个简单的管道和过滤器系统,目前我正在一次解析一个字节的输入流 我的数据流采用以下格式: ID(4字节)数据(8字节)ID(4字节)数据(8字节) 每个数据帧有6对ID和数据 解析这样一个流的最佳实践是什么?我希望能够过滤掉ID和一些数据,这样我将有一个只包含DATA01、DATA02等的表 例如,如何提取第一个id(000,例如整数)之后的第一个数据点(long),然后提取第二个id(001,整数)之后的第二个数据点(double) 我希望我能详细说明我的问题 提前感谢并问候您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) 我希望我能详细说明我的问题 提前感谢并问候您
飞利浦请提供一些示例代码
我猜你有一些
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这就是你最终使用的吗?如果是,我希望你接受我的答案:)非常感谢你的评论。我会尝试一下。非常感谢你的评论。我会尝试一下。