Java 比特布弗问题的解决方法
我使用Javolution实现了以下功能:Java 比特布弗问题的解决方法,java,bytebuffer,javolution,Java,Bytebuffer,Javolution,我使用Javolution实现了以下功能: public class RunScan extends Struct { public final Signed32 numOfClusters = new Signed32(); public final ClusterData[] clusters; public final Signed32 numOfRecons = new Signed32(); public final ReconData[] recons
public class RunScan extends Struct
{
public final Signed32 numOfClusters = new Signed32();
public final ClusterData[] clusters;
public final Signed32 numOfRecons = new Signed32();
public final ReconData[] recons ;
public RunScan (int numOfClusters, int numOfRecons)
{
this.numOfClusters.set(numOfClusters);
this.numOfRecons.set(numOfRecons);
clusters = array(new ClusterData[numOfClusters]);
recons = array(new ReconData[numOfRecons]);
}
}
public class ClusterData extends Struct
{
public final UTF8String scanType = new UTF8String(CommInterfaceFieldConstants.SCAN_TYPE_SIZE);
public final UTF8String patientId = new UTF8String(CommInterfaceFieldConstants.PATIENT_ID_SIZE);
.
.
.
}
public class ReconData extends Struct
{
public final UTF8String patientId = new UTF8String(CommInterfaceFieldConstants.PATIENT_ID_SIZE);
public final UTF8String scanSeriesId = new UTF8String(CommInterfaceFieldConstants.SCAN_SERIES_ID_SIZE);
.
.
.
}
在我们的通信类中,在将数据放入套接字之前,我们需要获取RunScan对象的bytes[],但是我们在//行中得到BufferUnderflowException,我的代码遇到了类似的情况。通常,对于当前结构对象,不能在与包含数组中元素数的成员相同的结构中定义可变长度数组 试着这样做:
public class RunScanHeader extends Struct
{
public final Signed32 numOfClusters = new Signed32();
public final Signed32 numOfRecons = new Signed32();
}
public class RunScanBody extends Struct
{
public final ClusterData[] clusters;
public final ReconData[] recons ;
public RunScan (int numOfClusters, int numOfRecons)
{
clusters = array(new ClusterData[numOfClusters]);
recons = array(new ReconData[numOfRecons]);
}
}
然后需要一个两阶段的方法来读写,首先读/写头部数据,然后读/写主体数据
很抱歉,目前我没有更多详细信息,如果您无法解决此问题,请告诉我,我将重新研究我的代码。我的代码遇到了类似的情况。通常,对于当前结构对象,不能在与包含数组中元素数的成员相同的结构中定义可变长度数组 试着这样做:
public class RunScanHeader extends Struct
{
public final Signed32 numOfClusters = new Signed32();
public final Signed32 numOfRecons = new Signed32();
}
public class RunScanBody extends Struct
{
public final ClusterData[] clusters;
public final ReconData[] recons ;
public RunScan (int numOfClusters, int numOfRecons)
{
clusters = array(new ClusterData[numOfClusters]);
recons = array(new ReconData[numOfRecons]);
}
}
然后需要一个两阶段的方法来读写,首先读/写头部数据,然后读/写主体数据
很抱歉,目前我没有更多详细信息,如果您无法解决此问题,请告诉我,我将重新查找代码。初始化顺序很重要,因为它定义了每个字段的位置。当该字段被声明为最常见情况时,您的初始化就完成了。或者,如果在构造函数中执行此操作,则必须记住,构造函数是在成员初始化之后调用的。以下是在构造函数中完成初始化的示例:
public class RunScan extends Struct {
public final Signed32 numOfClusters;
public final ClusterData[] clusters;
public final Signed32 numOfRecons;
public final ReconData[] recons ;
public RunScan (int numOfClusters, int numOfRecons) {
// Initialization done in the constructor for all members
// Order is important, it should match the declarative order to ensure proper positioning.
this.numOfClusters = new Signed32();
this.clusters = array(new ClusterData[numOfClusters]);
this.numOfRecons = new Signed32();
this.recons = array(new ReconData[numOfRecons]);
// Only after all the members have been initialized the set method can be used.
this.numOfClusters.set(numOfClusters);
this.numOfRecons.set(numOfRecons);
}
}
初始化顺序很重要,因为它定义了每个字段的位置。当该字段被声明为最常见情况时,您的初始化就完成了。或者,如果在构造函数中执行此操作,则必须记住,构造函数是在成员初始化之后调用的。以下是在构造函数中完成初始化的示例:
public class RunScan extends Struct {
public final Signed32 numOfClusters;
public final ClusterData[] clusters;
public final Signed32 numOfRecons;
public final ReconData[] recons ;
public RunScan (int numOfClusters, int numOfRecons) {
// Initialization done in the constructor for all members
// Order is important, it should match the declarative order to ensure proper positioning.
this.numOfClusters = new Signed32();
this.clusters = array(new ClusterData[numOfClusters]);
this.numOfRecons = new Signed32();
this.recons = array(new ReconData[numOfRecons]);
// Only after all the members have been initialized the set method can be used.
this.numOfClusters.set(numOfClusters);
this.numOfRecons.set(numOfRecons);
}
}
get将移动ByteBuffer的位置
scCmd.getByteBuffer.slice.getdest可能会解决移动位置和意外副作用的问题
scCmd.getByteBuffer.duplicate.getdest也可以解决您的问题,如果slice生成的原始缓冲区图片错误
此外,scCmd.getByteBuffer似乎创建了一个冗余引用,并且您正在使用相同的方法调用源引用和子引用
如果scCmd.getByteBuffer已经向您传递了一个切片,那么您对这些方法的冗余访问肯定会执行与计划不同的操作。get将移动ByteBuffer的位置
scCmd.getByteBuffer.slice.getdest可能会解决移动位置和意外副作用的问题
scCmd.getByteBuffer.duplicate.getdest也可以解决您的问题,如果slice生成的原始缓冲区图片错误
此外,scCmd.getByteBuffer似乎创建了一个冗余引用,并且您正在使用相同的方法调用源引用和子引用
如果scCmd.getByteBuffer已经向您传递了一个切片,那么您对这些方法的冗余访问肯定会做一些您计划之外的事情。感谢您的帮助。我将测试我们的服务器端是否准备好了。作为一般的非特定的库主题,考虑在处理原始字节[]类型数据时确保实现是客户机/服务器平台不可知的。例如,如果字节表示数字,则必须考虑endianess。总的来说,我对这个答案投了赞成票,因为它使用了一种性能更高/更一致的方法,即首先发送一个头,指示即将发生的事情的长度,然后发送变量数据包。这允许服务器读取固定的标题,然后动态分配内容并完全/高效地读取。感谢您的帮助。我将测试我们的服务器端是否准备好了。作为一般的非特定的库主题,考虑在处理原始字节[]类型数据时确保实现是客户机/服务器平台不可知的。例如,如果字节表示数字,则必须考虑endianess。总的来说,我对这个答案投了赞成票,因为它使用了一种性能更高/更一致的方法,即首先发送一个头,指示即将发生的事情的长度,然后发送变量数据包。这允许服务器读取固定的标题,然后动态分配内容并完全/高效地读取。感谢您的帮助。根据您的建议,避免了UnderflowException,但我仍然无法从ClusterData数组中获得正确的值numOfCluster值很好。当我将ByteBuffer转换为byte[]以便放入套接字时。我试过接受Jimn235的建议,但还是一样。因此,我必须编写自己的方法来手动创建ByteBuffer,并将RunScan的所有内容复制到该ByteBuffer中,然后将该ByteBuffer转换为byte[],谢谢您的帮助。根据你的建议
n、 虽然避免了UnderflowException,但我仍然无法从ClusterData数组中获得正确的值numOfCluster值很好。当我将ByteBuffer转换为byte[]以便放入套接字时。我试过接受Jimn235的建议,但还是一样。因此,我必须编写自己的方法来手动创建ByteBuffer,并将RunScan的所有内容复制到该ByteBuffer中,然后将该ByteBuffer转换为byte[]。您好Jimn235,谢谢您的建议。请参考我对Dautelle回复的评论。使用您的建议,我看不到不同的结果。我对您的复制代码感兴趣,只是想看看它是否能比您的描述更简单。如果没有完整的代码库,很难知道缓冲区的外观背后是什么。嗨,Jimn235,谢谢你的建议。请参考我对Dautelle回复的评论。使用您的建议,我看不到不同的结果。我对您的复制代码感兴趣,只是想看看它是否能比您的描述更简单。如果没有完整的代码库,就很难知道缓冲区的外观背后是什么。
public class RunScan extends Struct {
public final Signed32 numOfClusters;
public final ClusterData[] clusters;
public final Signed32 numOfRecons;
public final ReconData[] recons ;
public RunScan (int numOfClusters, int numOfRecons) {
// Initialization done in the constructor for all members
// Order is important, it should match the declarative order to ensure proper positioning.
this.numOfClusters = new Signed32();
this.clusters = array(new ClusterData[numOfClusters]);
this.numOfRecons = new Signed32();
this.recons = array(new ReconData[numOfRecons]);
// Only after all the members have been initialized the set method can be used.
this.numOfClusters.set(numOfClusters);
this.numOfRecons.set(numOfRecons);
}
}