我在Android项目中使用JNI代码,其中JNI本机函数需要short []参数.但是,原始数据存储为ByteBuffer.我正在尝试转换数据格式如下.
ByteBuffer rgbBuf = ByteBuffer.allocate(size);
...
short[] shortArray = (short[]) rgbBuf.asShortBuffer().array().clone();
Run Code Online (Sandbox Code Playgroud)
但是在运行上面显示的第二行代码时遇到以下问题:
E/AndroidRuntime(23923): Caused by: java.lang.UnsupportedOperationException
E/AndroidRuntime(23923): at Java.nio.ShortToByteBufferAdapter.protectedArray(ShortToByteBufferAdapter.java:169)
Run Code Online (Sandbox Code Playgroud)
任何人都可以提出实施转换的方法吗?
我们使用Java ByteBuffer与C++服务器进行套接字通信.我们知道Java是Big-endian,而Socket通信也是Big-endian.因此,只要字节流被Java接收并放入ByteBuffer,我们就会调用getInt()来获取值.没问题,没有转换.
但是,如果我们以某种方式将ByteBuffer字节顺序专门设置为Little-endian(我的同事实际上已经这样做了),
当数据放入ByteBuffer时,Java会自动将Big-endian转换为Little-endian吗?
那么Little-endian版本的getInt()会给你一个正确的值吗?
我想上面两个问题的答案是肯定的.但是当我尝试验证我的猜测并试图找到getInt()在ByteBuffer中的工作原理时,我发现它是一个抽象方法.ByteBuffer的唯一子类是MappedByteBuffer类,它没有实现抽象的getInt().那么getInt()方法的实现在哪里?
对于发送,因为我们使用Little-endian ByteBuffer,我们需要在放入套接字之前将它们转换为Big-endian字节.
问题
我需要将两个整数和一个可变长度的字符串转换为字节.
我做了什么
我将每种数据类型转换为字节数组,然后将它们添加到字节缓冲区中.之后我将该缓冲区复制到一个字节数组,如下所示.
byte[] nameByteArray = cityName.getBytes();
byte[] xByteArray = ByteBuffer.allocate(4).putInt(x).array();
byte[] yByteArray = ByteBuffer.allocate(4).putInt(y).array();
ByteBuffer byteBuffer = ByteBuffer.allocate(nameByteArray.length + xByteArray.length + yByteArray.length);
Run Code Online (Sandbox Code Playgroud)
现在这似乎有点多余.我当然可以将所有内容放入字节缓冲区并将其转换为字节数组.但是,我不知道我的字符串长度是多少.那么在这种情况下如何分配字节缓冲区呢?(要分配一个字节缓冲区,你必须指定它的容量)
我正在为java中基于移动设备的设备编写一个Web服务器.
这个网络服务器是单线程的,遵循nginx,node.js和类似的背后的想法:不产生多个线程只是在事件循环中使用异步操作.
虽然使用多线程网络服务器可能会在x86最近的cpu上提供更好的性能,但基于arm的单核cpu将需要做更多的工作.
为了澄清,我非常清楚C和我在C#中实现普通c或多线程的单线程Web服务器,利用Windows上的IOPS,但我在java中只编写了一个简单的web服务器,我想要替换它用这个新的.
现在,我正在使用java nio,并且我已经知道ByteBuffer在转换为字符串时非常慢但是这不是问题,因为我不需要做,事实上gaix maximium表演我想实现解析和比较字节级别.
我的问题是,解析字节缓冲区的方法更快?
我已经看到ByteBuffer支持get方法,它允许访问单个字节并向前移动光标,支持数组方法,返回支持数组,所以我的问题是哪种方法更快?
我可以直接在支持的数组上工作,或者我应该避免和使用get?
我想实现一个ByteBufferPool来重用bytebuffer,我会让线程知道它,在下面阅读,这可能是一个问题吗?
在某些情况下,我将比较字节到字节,应用掩码来处理区分大小写(我的意思是,如果第一个字节是G,第三个是T,第四个是空格(0x47,0x54和0x20)我可以处理请求作为一个GET)和其他情况下我需要比较字符串和字节数组,比如标题(我将循环通过字符串字符,将它们转换为字节并与字节进行比较).
对不起这些愚蠢的问题,但我不知道java规格,不知道内部java的东西,所以我需要信息:)
有人可以暗示一下吗?:)
PS:很明显,并非所有操作都可以以do-stuff-pause-continue-return方式处理,所以我将实现一个ThreadPool以避免线程创建惩罚
我目前有一个Java ByteBuffer,它已经拥有Big Endian格式的数据.然后我想写一个二进制文件作为Little Endian.
这是在Big Endian中编写文件的代码:
public void writeBinFile(String fileName, boolean append) throws FileNotFoundException, IOException
{
FileOutputStream outStream = null;
try
{
outStream = new FileOutputStream(fileName, append);
FileChannel out = outStream.getChannel();
byteBuff.position(byteBuff.capacity());
byteBuff.flip();
byteBuff.order(ByteOrder.LITTLE_ENDIAN);
out.write(byteBuff);
}
finally
{
if (outStream != null)
{
outStream.close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,byteBuff是一个以Big Endian格式填充的ByteBuffer.
我的最后一种方法是创建另一个缓冲区并将ByteBuffer设置为little endian然后从原始(big endian)缓冲区读取"getInt"值,并将值"setInt"设置为little endian缓冲区的强力方法.我想有更好的方法......
我有一个或多个ByteBuffers包含单个消息的一部分.现在我想阅读此消息,但我不想将N ByteBuffer复制到单个消息中.我的解析器期望单个ByteBuffer具有完整的消息,但是我的消息被分成N个ByteBuffers.
有没有办法将这些N ByteBuffers组合成一个没有字节复制的单个?我想象了ByteBuffer抽象类的某种智能实现,它由引擎盖下的这些ByteBuffer备份,只需调整指针并委托给正确的ByteBuffer.
如果您对我需要的原因感到好奇,请查看下面的BM&F/Bovespa协议.它们将消息分成块,并且它们可以在不同的数据包中无序出现,换句话说,相同的消息序列可以包含多个数据包,每个数据包都有一个消息块.我无法按顺序写入相同的ByteBuffer,因为这些块可能出现故障.:(
我错过了一些更聪明的东西吗?在下面给出了这个块协议,看起来没有办法顺序写入相同的ByteBuffer.:(

我的用例需要直接分配ByteBuffer,写入一次,然后由许多并发线程读取.所有读取都是绝对的,所以我从不关心缓冲区的状态(位置,限制,标记).
关于Keith Gregory的字节缓冲区的这篇文章警告说,即使绝对读取也不被认为是线程安全的:
ByteBufferBufferJavaDoc中介绍了线程安全性; 简短的版本是缓冲区不是线程安全的.显然,在没有竞争条件的情况下,您不能使用来自多个线程的相对定位,但即使绝对定位也无法保证(无论您在查看实现类后如何看待).
(强调我的)
由于这个警告,我在字节缓冲区的每次读取之前调用duplicate.这很容易,但每次读取时额外的对象分配让我很好奇为什么它实际上是必要的.
尽管Keith的向导免责声明,我确实看到了OpenJDK对直接字节缓冲区的绝对读取的实现:
public byte get(int i) {
return ((unsafe.getByte(ix(checkIndex(i)))));
}
Run Code Online (Sandbox Code Playgroud)
您可以看到它只是委托给Unsafe.getByte(long)"从给定内存地址获取值".
我知道可能存在不同的实现,但对于此操作而言,合理地不能保证线程安全吗?Buffer合同是否只是拒绝保证绝对读取的线程安全性,以避免部分线程安全类的混淆?或者如果警告对于并发写入是合理的,那么我的情况如何,在创建后字节缓冲区未被修改?此外,使用MappedByteBuffer替代品时会有什么变化吗?
有关:
我有一个byte[] bytes从ByteBuffer其中包含一个数据包.我想把数据包放入String.
目前我有以下内容
byte[] bytes = packet.array();
System.out.println("Packet String:" + new String(bytes));
Run Code Online (Sandbox Code Playgroud)
但后来我得到了以下输出
Packet String:E????<?@??@?.
03-22 04:30:28.187 9296-10152/willem.com.vpn I/System.out? ????J}?j???k?:??????????9???????
03-22 04:30:28.197 9296-10152/willem.com.vpn I/System.out? ??&?4????????ddrarpa??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
我用这样的编码尝试过它
System.out.println("Packet String:" + new String(bytes, Charset.forName("UTF-8")));
Run Code Online (Sandbox Code Playgroud)
但那不是正确的字符集.任何人都可以告诉我什么是?
因为它是jvm heap&gc,它何时发布?或者,它一直持续到流程终止?
我已经检查过:
但是所有答案都很模糊,没有人明确回答,是否有明确的答案?至少对于64位Linux上的Java 8.
我正在以下列方式构建BigInt由两个Longs 组成的数字:
val msb = -1L // some arbitrary long value, can be anything between Long.Min/MaxValue
val lsb = 25L // a second arbitrary long value
val bb = ByteBuffer
.allocate(17)
.put(0.toByte) // 1 byte
.putLong(msb) // 8 bytes
.putLong(lsb) // 8 bytes
val number = BigInt(bb.array) // in this case: 340282366920938463444927863358058659865
Run Code Online (Sandbox Code Playgroud)
我Byte在前面添加另一个0-的原因是为了保证结果是正数.否则,由于两个补码,结果BigInt 可能是负的.之后调用的算法期望大于或等于零的数字.
到现在为止还挺好.
我在翻转整个过程时遇到了麻烦 - 将BigInt后面的内容转换为两个Long(确切地说是用作输入的两个值).我不能只做以下事情:
val arr = number.toByteArray
val bb = ByteBuffer.wrap(arr) …Run Code Online (Sandbox Code Playgroud)