我正在研究Android应用程序(显然是Java),最近我更新了我的UDP阅读器代码.在这两个版本中,我设置了一些缓冲区并接收UDP数据包:
byte[] buf = new byte[10000];
short[] soundData = new short[1000];
DatagramPacket packet = new DatagramPacket (buf, buf.length);
socket.receive (packet);
Run Code Online (Sandbox Code Playgroud)
在初始版本中,我将数据一次放回一个字节(实际上是16个PCM音频数据):
for (int i = 0; i < count; i++)
soundData[i] = (short) (((buf[k++]&0xff) << 8) + (buf[k++]&0xff));
Run Code Online (Sandbox Code Playgroud)
在更新的版本中,我使用了一些我开始时不知道的很酷的Java工具:
bBuffer = ByteBuffer.wrap (buf);
sBuffer = bBuffer.asShortBuffer();
sBuffer.get (soundData, 0, count);
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,"计数"正在正确填充(我检查过).然而,我的流媒体音频似乎出现了新的问题 - 也许它的处理速度不够快 - 这对我来说没有任何意义.显然,缓冲区代码正在编译成三个以上的JVM代码语句,但是当我开始这个时,第二个版本会比第一个版本更快,这似乎是一个合理的假设.
很明显,我并不是说我的代码必须使用Java NIO缓冲区,但至少乍一看,它看起来似乎很难做到这一点.
任何人都有一个快速,简单的Java UDP阅读器的建议,以及是否有一个普遍接受的"最佳方式"?
谢谢,R.
我有一个包含大文件(100 MB)的ByteBuffer:
java.nio.ByteBuffer byteBuffer = ByteBuffer.wrap(multipartFile.getBytes());
writeChannel.write(byteBuffer);
writeChannel.closeFinally();
Run Code Online (Sandbox Code Playgroud)
我一次只能合法地写1 MB writeChannel.
如何切片ByteBuffer的内容,一次只写1 MB的切片到writeChannel?
我正在使用 ByteBuffer.allocateDirect() 分配一些缓冲内存以将文件读入内存,然后最终散列该文件字节并从中获取文件散列 (SHA)。输入文件的大小范围很大,从几 KB 到几 GB 不等。
我已经阅读了几个关于选择缓冲区大小的线程和页面(甚至一些在 SO 上)。有些人建议尝试选择本机 FileSystem 使用的一个,以尽量减少对部分块等进行读取操作的机会。比如4100字节的缓冲区,NTFS默认是4096,所以多出来的4位需要单独读操作,非常浪费。
所以坚持使用 2、1024、2048、4096、8192 等的幂。我看到一些推荐的缓冲区大小为 32KB,其他建议将缓冲区设置为输入文件的大小(对于小文件可能没问题,但是什么关于大文件?)。
坚持使用原生块大小的缓冲区有多重要?现代来说(假设现代 SATA 驱动器或更好的驱动器缓存至少有 8Mb,以及其他现代操作系统“魔法”来优化 I/O)缓冲区大小有多重要,我应该如何最好地确定将我的大小设置为多少?我可以静态设置它,还是动态确定它?感谢您的任何见解。
我正在 Java FX 应用程序中设置拖放。当我尝试从JavaDoc stuggest 中获取自定义数据时,Dragboard我得到了一个java.nio.HeapByteBuffer而不是一个Object。此字节缓冲区不能投给我的原始数据类型。
我在 Scala 工作,所以它的语法有点不同,但你明白了。但是,也许是因为我在 Scala 中才得到这个HeapByteBuffer而不是常规的Object?
好的,这里我将创建可以拖放的 JavaFX 控件。我要附上一个String和一个MyObject; 在String可以同时被检索MyObject不能。
请注意,我知道有更简单的方法可以将简单的字符串附加到拖动板上,这只是一个示例,表明它也MyObject应该可以从拖动板上检索。
在这里,我创建了一个可以拖动的自定义组件。拖动时,两个对象会附加到拖动板上:aMyObject和 a String。
class ToolboxItem
extends Label {
setOnDragDetected(new EventHandler[MouseEvent] {
def handle(event: MouseEvent) {
val dragboard = startDragAndDrop(TransferMode.COPY)
val content = new ClipboardContent()
content.put(DnDTarget.DndString, "sean is cool")
content.put(DnDTarget.DndObject, new MyObject)
dragboard.setContent(content)
event.consume()
}
}
Run Code Online (Sandbox Code Playgroud)
MyObject 为了开始,非常简单: …
最近我创建了一个包装器来读取和写入数据到一个byte数组中。为此,我一直在使用ArrayList<Byte>,但我想知道这是否是最有效的方法,因为:
addAll()不适用于byte数组(即使使用Arrays.asList(),它返回 me List<Byte[]>)。为了修复它,我只是循环并byte在每个循环中添加一个,但我想这假设了很多函数调用,因此它具有性能成本。byte[]从ArrayList。我无法从Byte[]to投射byte[],所以我必须使用循环。我知道ByteArrayInputStream并且ByteArrayOutputStream可以用于此,但它有一些不便之处:
readInt,readLEInt、readUInt、 等),而这些类只能读取/写入字节或字节数组。这不是真正的问题,因为我可以在包装器中修复它。但是第二个问题来了。ByteArrayInputStream和ByteArrayOutputStream。我不知道这些是否可以以某种方式同步,或者我每次写入包装器时都必须将一个的整个数据写入另一个。所以,我的问题来了:使用 aByteBuffer会更有效吗?我知道您可以从中获取integers,floats等,甚至可以更改字节顺序。我想知道的是,使用 aByteBuffer和 a之间是否存在真正的性能变化ArrayList<Byte>。
我正在寻找一种使用 Java NIO 从套接字通道读取字节的有效方法。任务很简单,我有一个解决方案,但我正在寻找一种更清洁、更有效的方法来解决这个问题。这是场景:
我的解决方案读取每个字节的数据字节并将每个字节与我的标记(在 UTF-8 代码页中的值为 10)进行比较。这是代码:
ByteBuffer res = ByteBuffer.allocate(512);
boolean completed = false;
try {
while (true) {
ByteBuffer tmp = ByteBuffer.allocate(1);
if(soc.read(tmp) == -1) {
break;
}
// set marker back to index 0
tmp.rewind();
byte cur = tmp.get();
res.put(cur);
// have we read newline?
if (cur == 10) {
doSomething(res);
res.clear();
}
}
} catch(Exception ex) {
handle(ex);
}
Run Code Online (Sandbox Code Playgroud)
即使这样做可以完成工作,也可能有更好的方法,即不需要在每次迭代后进行每字节比较。
谢谢你的帮助!
我是Java NIO的新手,我不确定如何做nio-ishly.
假设我已经从套接字读取了一些数据,ByteBuffer并使用get方法消耗了所有字节,但只有一个ByteBuffer.我知道下一件事将是四个字节,带有二进制格式的整数,所以我想使用getInt(),但只有int的第一个字节在缓冲区中.
对我来说很自然的事情是用连接中的更多字节填充缓冲区然后继续.如果我理解正确,我可以实现这一点
buf.compact();
buf.position(buf.limit());
buf.limit(buf.capacity());
Run Code Online (Sandbox Code Playgroud)
然后读取更多字节.
由于没有这种行为的flip()方法,但有方法,我想知道我的想法是否错误.有没有更好的方法来做到这一点?
如果连接传递长度+数据消息流,则自然会发生这种情况.
我正在做一个涉及音频处理的项目。
我正在从文件中提取一段音频,然后想对其进行一些处理。问题是我将音频数据作为字节数组获取,而我的处理是在双数组上(以及后来在复杂数组上......)。
我的问题是如何将收到的字节数组正确转换为双数组继续?
这是我的输入代码:
AudioFormat format = new AudioFormat(8000, 16, 1, true, true);
AudioInputStream in = AudioSystem.getAudioInputStream(WAVfile);
AudioInputStream din = null;
AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
8000,
16,
1,
2,
8000,
true);
din = AudioSystem.getAudioInputStream(decodedFormat, in);
TargetDataLine fileLine = AudioSystem.getTargetDataLine(decodedFormat);
fileLine .open(format);
fileLine .start();
int numBytesRead;
byte[] targetData = new byte[256]; // (samplingRate / 1000) * 32ms
while (true) {
numBytesRead = din.read(targetData, 0, targetData.length);
if (numBytesRead == -1) {
break;
}
double[] convertedData;
// Conversion code goes here...
processAudio(convertedData); …Run Code Online (Sandbox Code Playgroud) 当我尝试在文件中写入一个二进制文件,其值如下:
public static main(String[] args){
ByteBuffer output = ByteBuffer.allocate(80);
output.order(ByteOrder.BIG_ENDIAN);
output.putDouble(545.5);
appendByteArrayInFile("c:/myPath/", "test.bin", output.array());
}
private static void appendByteArrayInFile(String exportDirectory, String fileName, byte[] toAppendInFile) {
if (toAppendInFile != null) {
File targetExport = createPathAndFile(exportDirectory + fileName);
try (FileOutputStream output = new FileOutputStream(targetExport, true)) {
output.write(toAppendInFile);
} catch (Exception e) {
// no
}
}
}
private static File createPathAndFile(String path) {
File targetExport = new File(path);
targetExport.getParentFile().mkdirs();
return targetExport;
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我查看生成的文件时,似乎双端以小端方式放置,当我将ByteOrder切换为little-endian时,double是用big-endian编写的......但是当我放入int,endianness是正确的.
BigEndian中输出为double:
01000000 10000001 00001100 00000000 00000000 00000000 00000000 00000000 …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,它通过 XMLHttpRequest 加载用户文本并以二进制格式返回它。我知道 8、16 和 32 之间的主要区别是每个元素的字节数,但我不知道何时使用每个。
例如,对于我的应用程序,由于文本文件实际上可以包含任何可能的字符,哪一个最好?
我尝试了不同的文件,包括一个带有表情符号的文件,似乎在 Uint8Array 中表情符号占用了 4 个索引。
有什么理由让我不应该只使用 Uint8Array 还是有理由我应该在读取文件时动态选择?我已经阅读了每个文档的MDN文档,但除了字节大小之外,它似乎没有提供太多见解。
这是我目前用来加载文件的代码:
asset= new XMLHttpRequest();
asset.addEventListener('readystatechange', function load() {
if (asset.readyState == 4 && asset.data.status == 200) {
const arrayBuffer = asset.data.response;
if (arrayBuffer) asset.data = new Uint8Array(arrayBuffer);
}
}.bind(this), false);
// Error handling.
asset.responseType = 'arraybuffer';
asset.open('GET', asset.src);
asset.send();
Run Code Online (Sandbox Code Playgroud) bytebuffer ×10
java ×9
nio ×3
android ×1
arraylist ×1
arrays ×1
audio ×1
buffer ×1
byte ×1
bytearray ×1
endianness ×1
javafx ×1
javascript ×1
scala ×1
sockets ×1