我试图通过java.nio.ByteBuffer读取UTF8字符串.大小是一个unsinged int,当然,Java没有.我已经把这个值读成了很长的一段时间,所以我有了价值.
我的下一个问题是我不能用long创建一个字节数组,并且他长期回到int会导致它被签名.
我也尝试在缓冲区上使用limit(),但是再次使用int不长.
我正在做的具体事情是从类文件中读取UTF8字符串,因此缓冲区中只有UTF8字符串.
关于如何从ByteBuffer读取具有潜在长度的unsigned int的UTF8字符串的任何想法.
编辑:
SourceDebugExtension_attribute {
u2 attribute_name_index;
u4 attribute_length;
u1 debug_extension[attribute_length];
}
attribute_name_index
The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "SourceDebugExtension".
attribute_length
The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes. The value of the attribute_length item is thus the number of bytes …Run Code Online (Sandbox Code Playgroud) 我有一个叫做缓冲区的ByteBuffer.我想生成一个新的缓冲区,其中包含从buffer.position()到缓冲区末尾的所有字节,后跟从位置0到buffer.position() - 1 的所有字节.
本质上,我想将当前位置的字节移动到缓冲区的开头,同时将当前开始结束.
为了说明,如果这是我的ByteBuffer(P当前位置在哪里,数字0-9表示字节位置):
|0123456789|
P
Run Code Online (Sandbox Code Playgroud)
...然后我想要形成一个看起来像这样的新ByteBuffer:
|3456789012|
P
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所尝试的(并且不起作用):
ByteBuffer tmpByteBuffer = buffer.slice();
tmpByteBuffer.limit(buffer.capacity());
Run Code Online (Sandbox Code Playgroud)
这是错误(这是来自Android上的LogCat - 虽然我不认为该问题是特定于Android的):
12-22 03:49:44.303: ERROR/AndroidRuntime(10399): Uncaught handler: thread Thread-11 exiting due to uncaught exception
12-22 03:49:44.313: ERROR/AndroidRuntime(10399): java.lang.IllegalArgumentException
12-22 03:49:44.313: ERROR/AndroidRuntime(10399): at java.nio.Buffer.limit(Buffer.java:239)
12-22 03:49:44.313: ERROR/AndroidRuntime(10399): at com.chaimp.audiolistener.AudioListener.captureSamples(AudioListener.java:175)
12-22 03:49:44.313: ERROR/AndroidRuntime(10399): at com.chaimp.precisiontuner.PrecisionTuner$1.run(PrecisionTuner.java:28)
12-22 03:49:44.313: ERROR/AndroidRuntime(10399): at java.lang.Thread.run(Thread.java:1096)
Run Code Online (Sandbox Code Playgroud)
谁能告诉我我做错了什么?
而且,有更好的方法吗?
感谢您对此的任何帮助.
我正在尝试使用Kryo将对象读/写到磁盘:http://code.google.com/p/kryo/
情侣问题:
如何确定字节缓冲区的大小?如果我把它做得太小就会崩溃,太大会占用大量的内存,文件也很庞大.跟进,不应该知道kyro已经知道对象有多大,因为它是序列化的对象吗?
有什么方法可以将它们从ByteBuffer转换为字节数组并返回?
任何人都可以使用Kyro快速有效地读取/写入文件对象?我的令人讨厌的xml快了大约100倍(包括解析,而不仅仅是i/o)根据基准测试没有意义.我尝试使用ByteBuffer写入FileChannel.
我正在使用的协议要求将文件中的当前位置作为"无符号,网络字节顺序的4字节整数"发回.关于这个问题有几个问题,但他们假设我使用的是Integers,而不是Longs
我试图将其移植到NIO的ByteBuffer,以便它可以在套接字通道中发送:
long bytesTransfered = ... some number of bytes transfered...
//TODO: What does this actually do?
outBuffer[0] = (byte) ((bytesTransfered >> 24) & 0xff);
outBuffer[1] = (byte) ((bytesTransfered >> 16) & 0xff);
outBuffer[2] = (byte) ((bytesTransfered >> 8) & 0xff);
//TODO: Why does netbeans say this does nothing?
outBuffer[3] = (byte) ((bytesTransfered >> 0) & 0xff);
Run Code Online (Sandbox Code Playgroud)
他们在ByteBuffer中的任何方法都能实现这一目标吗?希望以一种更加明显,自我描述的方式,然后上面的位移魔法?
谁能告诉我分配零长度缓冲区的可能目的是什么?
ByteBuffer.allocate(0); // no IllegalArgumentException
Run Code Online (Sandbox Code Playgroud)
为什么设计 API 的人会这样做?
感谢您的评论和回答。
我希望会有这样的更新。:)
ByteBuffer.allocate(0); // no IllegalArgumentException
Run Code Online (Sandbox Code Playgroud) 我有一个空的 byteBuffer 分配为
data = ByteBuffer.allocateDirect(layerSize(0, faces - 1, 0, levels - 1) * layers);
按照这个答案,我尝试使用以下array()方法
public void setData(ByteBuffer data, int layer, int face, int level) {
int offset = offset(layer, face, level);
int levelSize = levelSize(level);
this.data.put(data.array(), offset, levelSize);
}
Run Code Online (Sandbox Code Playgroud)
但我得到:
Caused by: java.lang.UnsupportedOperationException
at java.nio.ByteBuffer.array(ByteBuffer.java:994)
Run Code Online (Sandbox Code Playgroud)
我尝试使用的源字节缓冲区以这种方式读取:
File file = new File(Load.class.getResource(fileName).getFile());
FileInputStream fileInputStream = new FileInputStream(file);
FileChannel fileChannel = fileInputStream.getChannel();
return loadKtx(fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, (int) file.length()));
public static Texture loadKtx(ByteBuffer byteBuffer) throws IOException {
... …Run Code Online (Sandbox Code Playgroud) 我正在尝试复制我在Objective-C(在iOS上)用Java生成的字节字符串但是遇到了麻烦.这是我想要制作的字符串:
"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
Run Code Online (Sandbox Code Playgroud)
我从4个整数的数组中得到该字符串[1,1,0,0]- 其中每个整数有4个字节.在这里查看了一堆问题之后,我尝试使用ByteBuffer以下方法在Java中构造该字符串:
ByteBuffer bytes = ByteBuffer.allocate(16);
bytes.putInt(1);
bytes.putInt(1);
bytes.putInt(0);
bytes.putInt(0);
String byteString = new String(bytes.array());
Run Code Online (Sandbox Code Playgroud)
然而,这给了我:
"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
Run Code Online (Sandbox Code Playgroud)
当我解压缩时,我得到的是一系列的[16777216, 16777216, 0, 0].显然我做错了,我希望有人可以指出我正确的方向.
我知道Java的ByteBuffer.clear()并不是真的要清除ByteBuffer中的所有数据,所以当我每次都使用StringBuilder.append()字符串时,最终结果总是在ByteBuffer中附加所有剩余的字符,这是旧的数据.写,所以如何解决这个问题?
int byteRead = -1;
int readCount = 0;
int BUFFER_SIZE = 256;
StringBuilder sb = new StringBuilder();
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
ReadableByteChannel readableByteChannel = Channels.newChannel(is);
while ((byteRead = readableByteChannel.read(buffer)) > 0 && readCount < 68) {
sb.append(new String(buffer.array(), "UTF-8"));
buffer.clear();
readCount++;
}
Run Code Online (Sandbox Code Playgroud) 我试图了解DirectByteBufferLinux 上的工作原理并编写了以下非常简单的程序以在 strace 下运行:
public static void main(String[] args){
while(true){
ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
}
}
Run Code Online (Sandbox Code Playgroud)
我期望实际上一些mmap或sys_brk系统调用直接从操作系统分配内存,但实际上它只是设置了请求页面的读写保护。我的意思是这样的:
mprotect(0x7fa9681ef000, 8192, PROT_READ|PROT_WRITE) = 0
Run Code Online (Sandbox Code Playgroud)
这似乎是分配直接缓冲区比分配堆缓冲区慢的原因,因为每次分配都需要系统调用。
如果我错了,请纠正我,但堆缓冲区分配(如果发生在 TLAB 内)相当于返回一个指向预分配堆内存的指针。
问题:为什么我们不能对直接内存做同样的事情?返回一个指向预分配内存的指针?
我是 java 新手,并开始使用 BitSet 和 ByteBuffer 实现 UDP 发送器,由于某种原因,我得到了我意想不到的行为。
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.BitSet;
public class Main
{
public static void main(String[] args) {
ByteBuffer out = ByteBuffer.allocate(2);
BitSet byt = new BitSet(8);
byt.set(0, true);
byt.set(1, false);
out.put(byt.toByteArray());
byt.set(0, true);
byt.set(1, false);
byt.set(2, true);
out.put(byt.toByteArray());
System.out.println("First byte is " + out.array()[0]+ " second is " + out.array()[1]);
}
}
Run Code Online (Sandbox Code Playgroud)
我在哪里得到输出
First byte is 1 second is 5
Run Code Online (Sandbox Code Playgroud)
我认为这是不行的,因为字节序是错误的
当我尝试运行这个时:
public class Main
{
public static void main(String[] args) { …Run Code Online (Sandbox Code Playgroud)