gpt4 book ai didi

java - 获取相对于原始 ByteBuffer 的直接 ByteBuffer 切片位置

转载 作者:搜寻专家 更新时间:2023-11-01 03:37:43 28 4
gpt4 key购买 nike

如果已知它是其他缓冲区?

我知道这可以通过非直接数组支持的 ByteBuffer 使用 arrayOffset() 方法来完成,如下所示:

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

我认为没有任何东西可以免费用于直接缓冲区。为了获得类似的东西,我能想到的最佳选择是扩展 ByteBuffer 以存储对创建它的缓冲区(父缓冲区)的引用以及相对于父缓冲区的零位置它的创建位置。

编辑:令人恼火的是,我似乎无法扩展 ByteBuffer,因为它的构造函数都不可见。我想我将不得不编写某种包装类。

最佳答案

这是可能的,使用反射。但根据您想要实现的目标,您应该考虑替代解决方案。目前尚不清楚您需要此偏移量的目的。 “务实”的建议是将缓冲区包装到一个简单的、自己的类中,比如

class SlicedBuffer {
int getBuffer() { ... }
Buffer getParent() { ... }
int getOffsetToParent() { ... }
}

并使用这个,但不清楚这是否适用于您的情况。

我将在此处发布使用反射的代码,但请注意

// Many things...
// ... can go ...
// ... wrong when...
// ... using reflection

所以这只是一个演示:

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

关于java - 获取相对于原始 ByteBuffer 的直接 ByteBuffer 切片位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25566539/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com