[英]Get direct ByteBuffer slice position relative to original ByteBuffer
Is there any way of getting a direct ByteBuffer
zero position relative to another, given only the two ByteBuffer
objects, if it is known that it is a subsequence of the other buffer? 如果知道它是另一个缓冲区的子序列,是否有任何方法可以获得相对于另一个的直接
ByteBuffer
零位置,只给出两个ByteBuffer
对象?
I know that this can be done with a non-direct array backed ByteBuffer
using the arrayOffset()
method like so: 我知道这可以通过使用
arrayOffset()
方法的非直接数组支持的ByteBuffer
来完成,如下所示:
int getRelativeBufferOffset(ByteBuffer parentBuffer, ByteBuffer childBuffer)
{
return childBuffer.arrayOffset() - parentBuffer.arrayOffset();
}
void example()
{
ByteBuffer buffer1 = ByteBuffer.allocate(10000);
buffer1 .position(22);
ByteBuffer buffer2 = buffer1.slice();
buffer2.position(55);
ByteBuffer buffer3 = buffer2.slice();
// returns 22
getRelativeBufferOffset(buffer1, buffer2);
// returns 55
getRelativeBufferOffset(buffer2, buffer3);
// returns 77
getRelativeBufferOffset(buffer1, buffer3);
}
I'm thinking that there isn't anything that exists for free for direct buffers. 我认为直接缓冲区没有任何免费存在的东西。 In order to get something similar the best option I can think of is to extend
ByteBuffer
to store a reference to the buffer from which it was created (the parent buffer) and the zero position relative to the parent's zero position at which it was created. 为了得到类似的东西,我能想到的最好的选择是扩展
ByteBuffer
来存储对创建它的缓冲区的引用(父缓冲区)和相对于父元素创建它的零位置的零位置。
EDIT: Annoyingly it looks like I can't extend ByteBuffer
because none of its constructors are visible. 编辑:令人讨厌的是,我看起来无法扩展
ByteBuffer
因为它的构造函数都不可见。 I guess I will have to write some kind of wrapper class instead. 我想我将不得不写一些包装类。
It is possible, using reflection. 使用反射是可能的。 But depending on what you want to achieve, you should consider alternative solutions.
但是,根据您想要实现的目标,您应该考虑替代解决方案。 It's not clear for which purpose you need this offset.
目前尚不清楚您需要这种偏移的目的。 The "pragmatic" recommendation would be to wrap the buffers into a simple, own class, like
“务实”的建议是将缓冲区包装成一个简单的,自己的类,如
class SlicedBuffer {
int getBuffer() { ... }
Buffer getParent() { ... }
int getOffsetToParent() { ... }
}
and work with this one, but it's not clear whether this is applicable in your case. 并与此合作,但目前尚不清楚这是否适用于您的情况。
I'll post the code using reflection here, but note that 我将在这里使用反射发布代码,但请注意
// Many things...
// ... can go ...
// ... wrong when...
// ... using reflection
so this is only a demonstration: 所以这只是一个示范:
import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
public class DirectByteBufferSliceOffsetsTest
{
public static void main(String[] args)
{
testArray();
testDirect();
}
private static void testArray()
{
System.out.println("Array: ");
ByteBuffer buffer1 = ByteBuffer.allocate(10000);
buffer1.position(22);
ByteBuffer buffer2 = buffer1.slice();
buffer2.position(55);
ByteBuffer buffer3 = buffer2.slice();
// prints 22
System.out.println(getRelativeBufferOffsetArray(buffer1, buffer2));
// prints 55
System.out.println(getRelativeBufferOffsetArray(buffer2, buffer3));
// prints 77
System.out.println(getRelativeBufferOffsetArray(buffer1, buffer3));
}
private static int getRelativeBufferOffsetArray(
ByteBuffer parentBuffer, ByteBuffer childBuffer)
{
return childBuffer.arrayOffset() - parentBuffer.arrayOffset();
}
private static void testDirect()
{
System.out.println("Direct: ");
ByteBuffer buffer1 = ByteBuffer.allocateDirect(10000);
buffer1.position(22);
ByteBuffer buffer2 = buffer1.slice();
buffer2.position(55);
ByteBuffer buffer3 = buffer2.slice();
// prints 22
System.out.println(getRelativeBufferOffsetDirect(buffer1, buffer2));
// prints 55
System.out.println(getRelativeBufferOffsetDirect(buffer2, buffer3));
// prints 77
System.out.println(getRelativeBufferOffsetDirect(buffer1, buffer3));
}
private static int getRelativeBufferOffsetDirect(
ByteBuffer parentBuffer, ByteBuffer childBuffer)
{
long parentAddress = getAddress(parentBuffer);
long childAddress = getAddress(childBuffer);
int offset = (int)(childAddress - parentAddress);
return offset;
}
private static long getAddress(Buffer buffer)
{
Field f = null;
try
{
f = Buffer.class.getDeclaredField("address");
f.setAccessible(true);
return f.getLong(buffer);
}
catch (NoSuchFieldException e)
{
// Many things...
e.printStackTrace();
}
catch (SecurityException e)
{
// ... can go ...
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
// ... wrong when...
e.printStackTrace();
}
catch (IllegalAccessException e)
{
// ... using reflection
e.printStackTrace();
}
finally
{
if (f != null)
{
f.setAccessible(false);
}
}
return 0;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.