标签: bytebuffer

ByteBuffer/IntBuffer/ShortBuffer Java类是否快速?

我正在研究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.

java android nio bytebuffer

5
推荐指数
1
解决办法
3219
查看次数

如何从ByteBuffer中获取连续切片?

我有一个包含大文件(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

java bytebuffer

5
推荐指数
1
解决办法
8548
查看次数

确定合适的缓冲区大小

我正在使用 ByteBuffer.allocateDirect() 分配一些缓冲内存以将文件读入内存,然后最终散列该文件字节并从中获取文件散列 (SHA)。输入文件的大小范围很大,从几 KB 到几 GB 不等。

我已经阅读了几个关于选择缓冲区大小的线程和页面(甚至一些在 SO 上)。有些人建议尝试选择本机 FileSystem 使用的一个,以尽量减少对部分块等进行读取操作的机会。比如4100字节的缓冲区,NTFS默认是4096,所以多出来的4位需要单独读操作,非常浪费。

所以坚持使用 2、1024、2048、4096、8192 等的幂。我看到一些推荐的缓冲区大小为 32KB,其他建议将缓冲区设置为输入文件的大小(对于小文件可能没问题,但是什么关于大文件?)。

坚持使用原生块大小的缓冲区有多重要?现代来说(假设现代 SATA 驱动器或更好的驱动器缓存至少有 8Mb,以及其他现代操作系统“魔法”来优化 I/O)缓冲区大小有多重要,我应该如何最好地确定将我的大小设置为多少?我可以静态设置它,还是动态确定它?感谢您的任何见解。

java buffer bytebuffer

5
推荐指数
1
解决办法
4339
查看次数

带有自定义数据格式的 JavaFX DragAndDrop

概览

我正在 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 为了开始,非常简单: …

java bytebuffer drag-and-drop scala javafx

5
推荐指数
1
解决办法
4170
查看次数

Java - ByteBuffer 还是 ArrayList&lt;Byte&gt;?

最近我创建了一个包装器来读取和写入数据到一个byte数组中。为此,我一直在使用ArrayList<Byte>,但我想知道这是否是最有效的方法,因为:

  • addAll()不适用于byte数组(即使使用Arrays.asList(),它返回 me List<Byte[]>)。为了修复它,我只是循环并byte在每个循环中添加一个,但我想这假设了很多函数调用,因此它具有性能成本。
  • 同样的情况,为得到一个byte[]ArrayList。我无法从Byte[]to投射byte[],所以我必须使用循环。
  • 我想存储 Byte 而不是 byte 会使用更多的内存。

我知道ByteArrayInputStream并且ByteArrayOutputStream可以用于此,但它有一些不便之处:

  • 我想实现以不同字节顺序读取不同数据类型的方法(例如readIntreadLEIntreadUInt、 等),而这些类只能读取/写入字节或字节数组。这不是真正的问题,因为我可以在包装器中修复它。但是第二个问题来了。
  • 我希望能够同时写入和读取,因为我正在使用它来解压缩一些文件。因此,要为它创建一个包装器,我需要同时包含ByteArrayInputStreamByteArrayOutputStream。我不知道这些是否可以以某种方式同步,或者我每次写入包装器时都必须将一个的整个数据写入另一个。

所以,我的问题来了:使用 aByteBuffer会更有效吗?我知道您可以从中获取integers,floats等,甚至可以更改字节顺序。我想知道的是,使用 aByteBuffer和 a之间是否存在真正的性能变化ArrayList<Byte>

java bytebuffer arraylist

5
推荐指数
1
解决办法
2009
查看次数

从 Java NIO socketchannel 读取字节直到到达标记

我正在寻找一种使用 Java NIO 从套接字通道读取字节的有效方法。任务很简单,我有一个解决方案,但我正在寻找一种更清洁、更有效的方法来解决这个问题。这是场景:

  1. 从套接字通道读取数据
  2. 这个数据是一个 UTF-8 编码的字符串
  3. 每行以\r\n结尾,长度未知
  4. 读完每一行后,我想对消息做点什么

我的解决方案读取每个字节的数据字节并将每个字节与我的标记(在 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 sockets nio bytebuffer

5
推荐指数
1
解决办法
3004
查看次数

如何从ByteBuffer获取只有1个剩余字节(Java NIO)

我是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()方法,但有方法,我想知道我的想法是否错误.有没有更好的方法来做到这一点?

如果连接传递长度+数据消息流,则自然会发生这种情况.

java nio bytebuffer

5
推荐指数
1
解决办法
436
查看次数

Java - 将 16 位有符号 pcm 音频数据数组转换为双数组

我正在做一个涉及音频处理的项目。

我正在从文件中提取一段音频,然后想对其进行一些处理。问题是我将音频数据作为字节数组获取,而我的处理是在双数组上(以及后来在复杂数组上......)。

我的问题是如何将收到的字节数组正确转换为双数组继续?

这是我的输入代码:

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)

java audio bytebuffer bytearray

5
推荐指数
1
解决办法
1862
查看次数

Java ByteBuffer BigEndian Double

当我尝试在文件中写入一个二进制文件,其值如下:

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)

java bytebuffer endianness

5
推荐指数
1
解决办法
215
查看次数

何时使用 Uint8Array、Uint16Array、Uint32Array

我有一个应用程序,它通过 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)

javascript arrays byte bytebuffer xmlhttprequest

5
推荐指数
1
解决办法
796
查看次数