java中未知长度的字节数组。

时间:2021-07-19 21:44:37

I am constructing an array of bytes in java and I don't know how long the array will be.

我在java中构造了一个字节数组,我不知道数组的长度。

I want some tool like Java's StringBuffer that you can just call .append(byte b) or .append(byte[] buf) and have it buffer all my bytes and return to me a byte array when I'm done. Is there a class that does for bytes what StringBuffer does for Strings? It does not look like the ByteBuffer class is what I'm looking for.

我想要一些工具,比如Java的StringBuffer,你可以调用。append(byte b)或。append(byte[] buf),并让它缓冲所有的字节,当我完成后返回给我一个字节数组。是否有一个类可以为字符串提供StringBuffer所做的字节?它看起来不像我要找的ByteBuffer类。

Anyone have a good solution?

有人有好的解决办法吗?

4 个解决方案

#1


102  

Try ByteArrayOutputStream. You can use write( byte[] ) and it will grow as needed.

ByteArrayOutputStream试试。您可以使用write(byte[]),它将根据需要增长。

#2


5  

Just to extend the previous answer, you can use ByteArrayOutputStream and it's method public void write(byte[] b, int off, int len), where parameters are:

为了扩展前面的答案,您可以使用ByteArrayOutputStream和它的方法public void write(byte[] b, int off, int len),其中参数为:

b - the data

b -数据

off - the start offset in the data

off——数据中的开始偏移量。

len - the number of bytes to write

len——写入的字节数。

If you want to use it as a "byte builder" and insert byte by byte, you can use this:

如果您想将其用作“字节构建器”,并按字节插入字节,您可以使用以下方法:

byte byteToInsert = 100;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(new byte[]{byteToInsert}, 0, 1);

Then you can use baos.toString() method to convert the array to string. The advantage is when you need to set up encoding of input, you can simply use i.e.:

然后可以使用baos.toString()方法将数组转换为字符串。好处是当您需要设置输入的编码时,您可以简单地使用:

baos.toString("Windows-1250")

#3


4  

I wrote one that is really easy to use and avoids a lot of byte array buffer copying.

我写了一个很容易使用的,并且避免了很多字节数组缓存复制。

It has one method called add.

它有一个方法叫做add。

You can add strings, bytes, byte, long, int, double, float, short, and chars to it.

您可以添加字符串、字节、字节、long、int、double、float、short和chars。

The API is easy to use and somewhat fail safe. It does not allow you to copy the buffer around and does not promote having two readers.

该API易于使用,并且在某种程度上是安全的。它不允许您复制缓冲区,也不允许有两个读取器。

It has a bounds check mode and a I KNOW WHAT I AM DOING MODE with no bounds checking.

它有一个边界检查模式,我知道我在做什么,没有边界检查。

The bounds check mode auto-grows it so there is no hassle.

边界检查模式自动增长,所以没有麻烦。

https://github.com/RichardHightower/boon/wiki/Auto-Growable-Byte-Buffer-like-a-ByteBuilder

https://github.com/RichardHightower/boon/wiki/Auto-Growable-Byte-Buffer-like-a-ByteBuilder

Here is a complete step by step guide on how to use it. It is on github.

这里有一个完整的步骤指南,教你如何使用它。它是在github上。

Java Boon - Auto Growable Byte Buffer like a ByteBuilder

Have you ever wanted an easy to use buffer array that grow automatically and/or you can give it a fix size and just add stuff to it? I have. I wrote one too.

您是否曾经想要一个易于使用的缓冲区数组,它可以自动地增长,或者您可以给它一个固定的大小,并添加一些东西到它?我有。我写了一个。

Look.. I can write strings to it (it converts them to UTF-8).

看. .我可以将字符串写入它(它将它们转换为UTF-8)。

    ByteBuf buf = new ByteBuf();
    buf.add(bytes("0123456789\n"));
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456END\n");

Then later I can read the String out of the buffer:

然后,我可以读出缓冲区中的字符串:

    String out = new String(buf.readAndReset(), 0, buf.len());
    assertEquals(66, buf.len());
    assertTrue(out.endsWith("END\n"));

I never have to set the size of the array. It will auto-grow as needed in an efficient manner.

我不需要设置数组的大小。它将以有效的方式自动增长。

If I know exactly how large my data is going to be than I can save some bounds checking by using createExact.

如果我知道我的数据到底有多大,我可以用createexactly来保存一些边界检查。

    ByteBuf buf = ByteBuf.createExact(66);
    buf.add(bytes("0123456789\n"));
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456END\n");
    assertEquals(66, buf.len());

If I use create exact, then I am saying... hey.. I know exactly how big it can grow to and it will never go over this number and if it does...you can hit me over the head with a sack of rocks!

如果我用的是精确的,那么我是说…嘿. .我知道它能长到多大,它永远不会超过这个数字,如果它…你可以用一袋石头打我的头!

The following hits you over the head with a sack of rocks! THROWS AN EXCEPTION!!!!

下面是一袋石头击中你的头!抛出异常! ! ! !

    ByteBuf buf = ByteBuf.createExact(22);
    buf.add(bytes("0123456789\n"));
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456END\n");

It works with doubles.

它的工作原理与双打。

    ByteBuf buf = ByteBuf.createExact(8);

    //add the double
    buf.add(10.0000000000001);

    byte[] bytes = buf.readAndReset();
    boolean worked = true;

    worked |= idxDouble(bytes, 0) == 10.0000000000001 || die("Double worked");

It works with float.

它与*浮动。

    ByteBuf buf = ByteBuf.createExact(8);

    //add the float
    buf.add(10.001f);

    byte[] bytes = buf.readAndReset();
    boolean worked = true;

    worked |= buf.len() == 4 || die("Float worked");


    //read the float
    float flt = idxFloat(bytes, 0);

    worked |= flt == 10.001f || die("Float worked");

It works with int.

它使用int。

    ByteBuf buf = ByteBuf.createExact(8);

    //Add the int to the array
    buf.add(99);

    byte[] bytes = buf.readAndReset();
    boolean worked = true;


    //Read the int back
    int value = idxInt(bytes, 0);

    worked |= buf.len() == 4 || die("Int worked length = 4");
    worked |= value == 99 || die("Int worked value was 99");

It works with char.

它使用char。

    ByteBuf buf = ByteBuf.createExact(8);

    //Add the char to the array
    buf.add('c');

    byte[] bytes = buf.readAndReset();
    boolean worked = true;


    //Read the char back
    int value = idxChar(bytes, 0);

    worked |= buf.len() == 2 || die("char worked length = 4");
    worked |= value == 'c' || die("char worked value was 'c'");

It works with short.

它与短。

    ByteBuf buf = ByteBuf.createExact(8);

    //Add the short to the array
    buf.add((short)77);

    byte[] bytes = buf.readAndReset();
    boolean worked = true;


    //Read the short back
    int value = idxShort(bytes, 0);

    worked |= buf.len() == 2 || die("short worked length = 2");
    worked |= value == 77 || die("short worked value was 77");

It even works with bytes.

它甚至可以使用字节。

    ByteBuf buf = ByteBuf.createExact(8);

    //Add the byte to the array
    buf.add( (byte)33 );

    byte[] bytes = buf.readAndReset();
    boolean worked = true;


    //Read the byte back
    int value = idx(bytes, 0);

    worked |= buf.len() == 1 || die("byte worked length = 1");
    worked |= value == 33 || die("byte worked value was 33");

You can add all sorts of primitives to your byte array.

您可以将所有类型的原语添加到字节数组中。

    boolean worked = true;
    ByteBuf buf = ByteBuf.create(1);

    //Add the various to the array
    buf.add( (byte)  1 );
    buf.add( (short) 2 );
    buf.add( (char)  3 );
    buf.add(         4 );
    buf.add( (float) 5 );
    buf.add( (long)  6 );
    buf.add( (double)7 );

    worked |= buf.len() == 29 || die("length = 29");


    byte[] bytes = buf.readAndReset();

    byte myByte;
    short myShort;
    char myChar;
    int myInt;
    float myFloat;
    long myLong;
    double myDouble;

Now we just verify that we can read everything back.

现在我们来验证一下,我们可以把所有的东西都读回来。

    myByte    =   idx       ( bytes, 0 );
    myShort   =   idxShort  ( bytes, 1 );
    myChar    =   idxChar   ( bytes, 3 );
    myInt     =   idxInt    ( bytes, 5 );
    myFloat   =   idxFloat  ( bytes, 9 );
    myLong   =    idxLong   ( bytes, 13 );
    myDouble  =   idxDouble ( bytes, 21 );

    worked |= myByte   == 1 || die("value was 1");
    worked |= myShort  == 2 || die("value was 2");
    worked |= myChar   == 3 || die("value was 3");
    worked |= myInt    == 4 || die("value was 4");
    worked |= myFloat  == 5 || die("value was 5");
    worked |= myLong   == 6 || die("value was 6");
    worked |= myDouble == 7 || die("value was 7");

Once you call

一旦你叫

 byte[] bytes = buf.readAndReset() 

then you are saying that you are done with the ByteBuffer!

然后你说你已经完成了ByteBuffer!

Once you ask for the bytes, it becomes useless as it sets the internal byte array to nothing.

一旦您请求字节,它就变得无用,因为它将内部字节数组设置为零。

When you call readAndReset, it is giving you its buffer. Here is my internal state, you can have it, but I am going to set it to null so nobody else uses it.

当你调用readAndReset时,它会给你缓冲。这是我的内部状态,你可以用它,但我要把它设为空,所以没有人用它。

It is ok. Just create another if you are sure only one instance at a time is using the buffer (byte []).

它是好的。如果您每次只确定一个实例,那么就创建另一个实例,即使用缓冲区(字节[])。

You can even use the buffer you were just using as in

您甚至可以使用刚才使用的缓冲区。

ByteBuf buf2 = new ByteBuf.create(bytes); 

This is because no buffer gets copied. ByteBuf writes to the buffer you give it. If you want another copy to be given to ByteBuf then do this:

这是因为没有复制缓冲区。ByteBuf将写入到您所提供的缓冲区。如果你想要另一个副本给ByteBuf,那么就这样做:

ByteBuf buf2 = new ByteBuf.create( copy(bytes) ); 

This is boon after all. :)

这毕竟是好事。:)

Come check out boon. You get the above class and idx, and idxInt and idxLong for free!

来看看福音。您得到了上面的类和idx,以及idxInt和idxLong免费!

https://github.com/RichardHightower/boon/

https://github.com/RichardHightower/boon/

#4


1  

Let's see. There is the ByteBuffer class in Java.

让我们来看看。Java中有ByteBuffer类。

http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html

http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html

It has bulk methods that transfer contiguous sequences of bytes from a byte array to hardware buffers. It would do the trick.

它有大量的方法将字节数组中的连续字节序列传输到硬件缓冲区。它会成功的。

It also has absolute and relative get and put methods that read and write byte[]s and other primitives to / for the byte buffer.

它还具有绝对和相对的get和put方法,这些方法可以读取和写入字节()和其他原语(字节缓冲区)。

It also has methods for compacting, duplicating, and slicing a byte buffer.

它还具有压缩、复制和切割字节缓冲区的方法。

// Creates an empty ByteBuffer with a 1024 byte capacity
ByteBuffer buf = ByteBuffer.allocate(1024);

// Get the buffer's capacity
int capacity = buf.capacity(); // 10

buf.put((byte)0xAA); // position=0

// Set the position
buf.position(500);

buf.put((byte)0xFF);

// Read the position 501
int pos = buf.position(); 

// Get remaining byte count
int remaining = buf.remaining(); (capacity - position)

It also has a bulk put to put an array, which is pretty close to the append you were asking for:

它也有一个大容量放置一个数组,它非常接近你所要求的附加部分:

public final ByteBuffer put(byte[] src)

See: http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#put(byte[])

见:http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html(byte[])

I wrote my own little lib for manipulating byte arrays. :)

我为操作字节数组编写了自己的小库。:)

You can add them like so

你可以把它们加起来。

byte [] a = ...
byte [] b = ...
byte [] c = ...

a = add(a, b);
a = add(a, c);

this would give you all of the contents of b, and c after the contents for a.

这将给出b的所有内容,以及a的内容。

If you wanted to grow a by 21, you could do the following:

如果你想在21岁时增长a,你可以做到以下几点:

a = grow( letters,  21);

If you wanted to double the size of a, you could do the following:

如果你想让a的大小增加一倍,你可以这样做:

a = grow( letters,  21);

See...

看到……

https://github.com/RichardHightower/boon/blob/master/src/main/java/org/boon/core/primitive/Byt.java

https://github.com/RichardHightower/boon/blob/master/src/main/java/org/boon/core/primitive/Byt.java

    byte[] letters =
            arrayOfByte(500);

    assertEquals(
            500,
            len(letters)
    );

Create

创建

    byte[] letters =
            array((byte)0, (byte)1, (byte)2, (byte)3);

    assertEquals(
            4,
            len(letters)
    );

Index

指数

    byte[] letters =
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d');

    assertEquals(
            'a',
            idx(letters, 0)
    );


    assertEquals(
            'd',
            idx(letters, -1)
    );


    assertEquals(
            'd',
            idx(letters, letters.length - 1)
    );


    idx(letters, 1, (byte)'z');

    assertEquals(
            (byte)'z',
            idx(letters, 1)
    );

Contains

包含

    byte[] letters =
            array((byte)'a',(byte) 'b', (byte)'c', (byte)'d');


    assertTrue(
            in((byte)'a', letters)
    );

    assertFalse(
            in((byte)'z', letters)
    );

Slice:

片:

    byte[] letters =
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d');


    assertArrayEquals(
            array((byte)'a', (byte)'b'),
            slc(letters, 0, 2)
    );

    assertArrayEquals(
            array((byte)'b', (byte)'c'),
            slc(letters, 1, -1)
    );

    //>>> letters[2:]
    //['c', 'd']
    //>>> letters[-2:]
    //['c', 'd']

    assertArrayEquals(
            array((byte)'c', (byte)'d'),
            slc(letters, -2)
    );


    assertArrayEquals(
            array((byte)'c', (byte)'d'),
            slc(letters, 2)
    );


    //>>> letters[:-2]
    //     ['a', 'b']
    assertArrayEquals(
            array((byte)'a', (byte)'b'),
            slcEnd(letters, -2)
    );


    //>>> letters[:-2]
    //     ['a', 'b']
    assertArrayEquals(
            array((byte)'a',(byte) 'b'),
            slcEnd(letters, 2)
    );

Grow

成长

    byte[] letters =
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e');

    letters = grow( letters,  21);


    assertEquals(
            'e',
            idx(letters, 4)
    );


    assertEquals(
            'a',
            idx(letters, 0)
    );




    assertEquals(
            len(letters),
            26
    );


    assertEquals(
            '\0',
            idx(letters, 20)
    );

Shrink:

萎缩:

    letters =  shrink ( letters, 23 );

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c'),
            letters

    );

Copy:

复制:

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e'),
            copy(array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e'))

    );

Add:

添加:

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'),
            add(array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e'), (byte)'f') );

The add actually adds them together by using System.arraycopy (considering Unsafe, but not yet).

添加实际上是通过使用系统将它们加在一起。arraycopy(考虑不安全,但还没有)。

Add one array to another:

将一个数组添加到另一个数组:

    assertArrayEquals(
            array(     (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'),
            add( array((byte)'a', (byte)'b', (byte)'c', (byte)'d'), array((byte)'e', (byte)'f') )

    );

Insert:

插入:

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g'),
            insert( array((byte)'a', (byte)'b', (byte)'d', (byte)'e', (byte)'f', (byte)'g'), 2, (byte)'c' )

    );

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g'),
            insert( array((byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g'), 0, (byte)'a' )

    );

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g'),
            insert( array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'g'), 5, (byte)'f' )

    );

Here is a peek at a few of the methods:

以下是一些方法:

public static byte[] grow(byte [] array, final int size) {
    Objects.requireNonNull(array);

    byte [] newArray  = new byte[array.length + size];
    System.arraycopy(array, 0, newArray, 0, array.length);
    return newArray;
}



public static byte[] grow(byte [] array) {
    Objects.requireNonNull(array);

    byte [] newArray  = new byte[array.length *2];
    System.arraycopy(array, 0, newArray, 0, array.length);
    return newArray;
}


public static byte[] shrink(byte[] array, int size) {
    Objects.requireNonNull(array);

    byte[] newArray = new byte[array.length - size];

    System.arraycopy(array, 0, newArray, 0, array.length-size);
    return newArray;
}




public static byte[] copy(byte[] array) {
    Objects.requireNonNull(array);
    byte[] newArray = new byte[array.length];
    System.arraycopy(array, 0, newArray, 0, array.length);
    return newArray;
}


public static byte[] add(byte[] array, byte v) {
    Objects.requireNonNull(array);
    byte[] newArray = new byte[array.length + 1];
    System.arraycopy(array, 0, newArray, 0, array.length);
    newArray[array.length] = v;
    return newArray;
}

public static byte[] add(byte[] array, byte[] array2) {
    Objects.requireNonNull(array);
    byte[] newArray = new byte[array.length + array2.length];
    System.arraycopy(array, 0, newArray, 0, array.length);
    System.arraycopy(array2, 0, newArray, array.length, array2.length);
    return newArray;
}



public static byte[] insert(final byte[] array, final int idx, final byte v) {
    Objects.requireNonNull(array);

    if (idx >= array.length) {
        return add(array, v);
    }

    final int index = calculateIndex(array, idx);

    //Object newArray = Array.newInstance(array.getClass().getComponentType(), array.length+1);
    byte [] newArray = new byte[array.length+1];

    if (index != 0) {
        /* Copy up to the location in the array before the index. */
        /*                 src     sbegin  dst       dbegin   length of copy */
        System.arraycopy( array,   0,      newArray, 0,       index );
    }


    boolean lastIndex = index == array.length -1;
    int remainingIndex = array.length - index;

    if (lastIndex ) {
        /* Copy the area after the insert. Make sure we don't write over the end. */
        /*                 src  sbegin   dst       dbegin     length of copy */
        System.arraycopy(array, index,   newArray, index + 1, remainingIndex );

    } else {
        /* Copy the area after the insert.  */
        /*                 src  sbegin   dst       dbegin     length of copy */
        System.arraycopy(array, index,   newArray, index + 1, remainingIndex );

    }

    newArray[index] = v;
    return  newArray;
}


public static byte[] insert(final byte[] array, final int fromIndex, final byte[] values) {
    Objects.requireNonNull(array);

    if (fromIndex >= array.length) {
        return add(array, values);
    }

    final int index = calculateIndex(array, fromIndex);

    //Object newArray = Array.newInstance(array.getClass().getComponentType(), array.length+1);
    byte [] newArray = new byte[array.length +  values.length];

    if (index != 0) {
        /* Copy up to the location in the array before the index. */
        /*                 src     sbegin  dst       dbegin   length of copy */
        System.arraycopy( array,   0,      newArray, 0,       index );
    }


    boolean lastIndex = index == array.length -1;

    int toIndex = index + values.length;
    int remainingIndex = newArray.length - toIndex;

    if (lastIndex ) {
        /* Copy the area after the insert. Make sure we don't write over the end. */
        /*                 src  sbegin   dst       dbegin     length of copy */
        System.arraycopy(array, index,   newArray, index + values.length, remainingIndex );

    } else {
        /* Copy the area after the insert.  */
        /*                 src  sbegin   dst       dbegin     length of copy */
        System.arraycopy(array, index,   newArray, index + values.length, remainingIndex );

    }

    for (int i = index, j=0; i < toIndex; i++, j++) {
        newArray[ i ] = values[ j ];
    }
    return  newArray;
}

More....

更多....

#1


102  

Try ByteArrayOutputStream. You can use write( byte[] ) and it will grow as needed.

ByteArrayOutputStream试试。您可以使用write(byte[]),它将根据需要增长。

#2


5  

Just to extend the previous answer, you can use ByteArrayOutputStream and it's method public void write(byte[] b, int off, int len), where parameters are:

为了扩展前面的答案,您可以使用ByteArrayOutputStream和它的方法public void write(byte[] b, int off, int len),其中参数为:

b - the data

b -数据

off - the start offset in the data

off——数据中的开始偏移量。

len - the number of bytes to write

len——写入的字节数。

If you want to use it as a "byte builder" and insert byte by byte, you can use this:

如果您想将其用作“字节构建器”,并按字节插入字节,您可以使用以下方法:

byte byteToInsert = 100;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(new byte[]{byteToInsert}, 0, 1);

Then you can use baos.toString() method to convert the array to string. The advantage is when you need to set up encoding of input, you can simply use i.e.:

然后可以使用baos.toString()方法将数组转换为字符串。好处是当您需要设置输入的编码时,您可以简单地使用:

baos.toString("Windows-1250")

#3


4  

I wrote one that is really easy to use and avoids a lot of byte array buffer copying.

我写了一个很容易使用的,并且避免了很多字节数组缓存复制。

It has one method called add.

它有一个方法叫做add。

You can add strings, bytes, byte, long, int, double, float, short, and chars to it.

您可以添加字符串、字节、字节、long、int、double、float、short和chars。

The API is easy to use and somewhat fail safe. It does not allow you to copy the buffer around and does not promote having two readers.

该API易于使用,并且在某种程度上是安全的。它不允许您复制缓冲区,也不允许有两个读取器。

It has a bounds check mode and a I KNOW WHAT I AM DOING MODE with no bounds checking.

它有一个边界检查模式,我知道我在做什么,没有边界检查。

The bounds check mode auto-grows it so there is no hassle.

边界检查模式自动增长,所以没有麻烦。

https://github.com/RichardHightower/boon/wiki/Auto-Growable-Byte-Buffer-like-a-ByteBuilder

https://github.com/RichardHightower/boon/wiki/Auto-Growable-Byte-Buffer-like-a-ByteBuilder

Here is a complete step by step guide on how to use it. It is on github.

这里有一个完整的步骤指南,教你如何使用它。它是在github上。

Java Boon - Auto Growable Byte Buffer like a ByteBuilder

Have you ever wanted an easy to use buffer array that grow automatically and/or you can give it a fix size and just add stuff to it? I have. I wrote one too.

您是否曾经想要一个易于使用的缓冲区数组,它可以自动地增长,或者您可以给它一个固定的大小,并添加一些东西到它?我有。我写了一个。

Look.. I can write strings to it (it converts them to UTF-8).

看. .我可以将字符串写入它(它将它们转换为UTF-8)。

    ByteBuf buf = new ByteBuf();
    buf.add(bytes("0123456789\n"));
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456END\n");

Then later I can read the String out of the buffer:

然后,我可以读出缓冲区中的字符串:

    String out = new String(buf.readAndReset(), 0, buf.len());
    assertEquals(66, buf.len());
    assertTrue(out.endsWith("END\n"));

I never have to set the size of the array. It will auto-grow as needed in an efficient manner.

我不需要设置数组的大小。它将以有效的方式自动增长。

If I know exactly how large my data is going to be than I can save some bounds checking by using createExact.

如果我知道我的数据到底有多大,我可以用createexactly来保存一些边界检查。

    ByteBuf buf = ByteBuf.createExact(66);
    buf.add(bytes("0123456789\n"));
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456END\n");
    assertEquals(66, buf.len());

If I use create exact, then I am saying... hey.. I know exactly how big it can grow to and it will never go over this number and if it does...you can hit me over the head with a sack of rocks!

如果我用的是精确的,那么我是说…嘿. .我知道它能长到多大,它永远不会超过这个数字,如果它…你可以用一袋石头打我的头!

The following hits you over the head with a sack of rocks! THROWS AN EXCEPTION!!!!

下面是一袋石头击中你的头!抛出异常! ! ! !

    ByteBuf buf = ByteBuf.createExact(22);
    buf.add(bytes("0123456789\n"));
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456789\n");
    buf.add("0123456END\n");

It works with doubles.

它的工作原理与双打。

    ByteBuf buf = ByteBuf.createExact(8);

    //add the double
    buf.add(10.0000000000001);

    byte[] bytes = buf.readAndReset();
    boolean worked = true;

    worked |= idxDouble(bytes, 0) == 10.0000000000001 || die("Double worked");

It works with float.

它与*浮动。

    ByteBuf buf = ByteBuf.createExact(8);

    //add the float
    buf.add(10.001f);

    byte[] bytes = buf.readAndReset();
    boolean worked = true;

    worked |= buf.len() == 4 || die("Float worked");


    //read the float
    float flt = idxFloat(bytes, 0);

    worked |= flt == 10.001f || die("Float worked");

It works with int.

它使用int。

    ByteBuf buf = ByteBuf.createExact(8);

    //Add the int to the array
    buf.add(99);

    byte[] bytes = buf.readAndReset();
    boolean worked = true;


    //Read the int back
    int value = idxInt(bytes, 0);

    worked |= buf.len() == 4 || die("Int worked length = 4");
    worked |= value == 99 || die("Int worked value was 99");

It works with char.

它使用char。

    ByteBuf buf = ByteBuf.createExact(8);

    //Add the char to the array
    buf.add('c');

    byte[] bytes = buf.readAndReset();
    boolean worked = true;


    //Read the char back
    int value = idxChar(bytes, 0);

    worked |= buf.len() == 2 || die("char worked length = 4");
    worked |= value == 'c' || die("char worked value was 'c'");

It works with short.

它与短。

    ByteBuf buf = ByteBuf.createExact(8);

    //Add the short to the array
    buf.add((short)77);

    byte[] bytes = buf.readAndReset();
    boolean worked = true;


    //Read the short back
    int value = idxShort(bytes, 0);

    worked |= buf.len() == 2 || die("short worked length = 2");
    worked |= value == 77 || die("short worked value was 77");

It even works with bytes.

它甚至可以使用字节。

    ByteBuf buf = ByteBuf.createExact(8);

    //Add the byte to the array
    buf.add( (byte)33 );

    byte[] bytes = buf.readAndReset();
    boolean worked = true;


    //Read the byte back
    int value = idx(bytes, 0);

    worked |= buf.len() == 1 || die("byte worked length = 1");
    worked |= value == 33 || die("byte worked value was 33");

You can add all sorts of primitives to your byte array.

您可以将所有类型的原语添加到字节数组中。

    boolean worked = true;
    ByteBuf buf = ByteBuf.create(1);

    //Add the various to the array
    buf.add( (byte)  1 );
    buf.add( (short) 2 );
    buf.add( (char)  3 );
    buf.add(         4 );
    buf.add( (float) 5 );
    buf.add( (long)  6 );
    buf.add( (double)7 );

    worked |= buf.len() == 29 || die("length = 29");


    byte[] bytes = buf.readAndReset();

    byte myByte;
    short myShort;
    char myChar;
    int myInt;
    float myFloat;
    long myLong;
    double myDouble;

Now we just verify that we can read everything back.

现在我们来验证一下,我们可以把所有的东西都读回来。

    myByte    =   idx       ( bytes, 0 );
    myShort   =   idxShort  ( bytes, 1 );
    myChar    =   idxChar   ( bytes, 3 );
    myInt     =   idxInt    ( bytes, 5 );
    myFloat   =   idxFloat  ( bytes, 9 );
    myLong   =    idxLong   ( bytes, 13 );
    myDouble  =   idxDouble ( bytes, 21 );

    worked |= myByte   == 1 || die("value was 1");
    worked |= myShort  == 2 || die("value was 2");
    worked |= myChar   == 3 || die("value was 3");
    worked |= myInt    == 4 || die("value was 4");
    worked |= myFloat  == 5 || die("value was 5");
    worked |= myLong   == 6 || die("value was 6");
    worked |= myDouble == 7 || die("value was 7");

Once you call

一旦你叫

 byte[] bytes = buf.readAndReset() 

then you are saying that you are done with the ByteBuffer!

然后你说你已经完成了ByteBuffer!

Once you ask for the bytes, it becomes useless as it sets the internal byte array to nothing.

一旦您请求字节,它就变得无用,因为它将内部字节数组设置为零。

When you call readAndReset, it is giving you its buffer. Here is my internal state, you can have it, but I am going to set it to null so nobody else uses it.

当你调用readAndReset时,它会给你缓冲。这是我的内部状态,你可以用它,但我要把它设为空,所以没有人用它。

It is ok. Just create another if you are sure only one instance at a time is using the buffer (byte []).

它是好的。如果您每次只确定一个实例,那么就创建另一个实例,即使用缓冲区(字节[])。

You can even use the buffer you were just using as in

您甚至可以使用刚才使用的缓冲区。

ByteBuf buf2 = new ByteBuf.create(bytes); 

This is because no buffer gets copied. ByteBuf writes to the buffer you give it. If you want another copy to be given to ByteBuf then do this:

这是因为没有复制缓冲区。ByteBuf将写入到您所提供的缓冲区。如果你想要另一个副本给ByteBuf,那么就这样做:

ByteBuf buf2 = new ByteBuf.create( copy(bytes) ); 

This is boon after all. :)

这毕竟是好事。:)

Come check out boon. You get the above class and idx, and idxInt and idxLong for free!

来看看福音。您得到了上面的类和idx,以及idxInt和idxLong免费!

https://github.com/RichardHightower/boon/

https://github.com/RichardHightower/boon/

#4


1  

Let's see. There is the ByteBuffer class in Java.

让我们来看看。Java中有ByteBuffer类。

http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html

http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html

It has bulk methods that transfer contiguous sequences of bytes from a byte array to hardware buffers. It would do the trick.

它有大量的方法将字节数组中的连续字节序列传输到硬件缓冲区。它会成功的。

It also has absolute and relative get and put methods that read and write byte[]s and other primitives to / for the byte buffer.

它还具有绝对和相对的get和put方法,这些方法可以读取和写入字节()和其他原语(字节缓冲区)。

It also has methods for compacting, duplicating, and slicing a byte buffer.

它还具有压缩、复制和切割字节缓冲区的方法。

// Creates an empty ByteBuffer with a 1024 byte capacity
ByteBuffer buf = ByteBuffer.allocate(1024);

// Get the buffer's capacity
int capacity = buf.capacity(); // 10

buf.put((byte)0xAA); // position=0

// Set the position
buf.position(500);

buf.put((byte)0xFF);

// Read the position 501
int pos = buf.position(); 

// Get remaining byte count
int remaining = buf.remaining(); (capacity - position)

It also has a bulk put to put an array, which is pretty close to the append you were asking for:

它也有一个大容量放置一个数组,它非常接近你所要求的附加部分:

public final ByteBuffer put(byte[] src)

See: http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#put(byte[])

见:http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html(byte[])

I wrote my own little lib for manipulating byte arrays. :)

我为操作字节数组编写了自己的小库。:)

You can add them like so

你可以把它们加起来。

byte [] a = ...
byte [] b = ...
byte [] c = ...

a = add(a, b);
a = add(a, c);

this would give you all of the contents of b, and c after the contents for a.

这将给出b的所有内容,以及a的内容。

If you wanted to grow a by 21, you could do the following:

如果你想在21岁时增长a,你可以做到以下几点:

a = grow( letters,  21);

If you wanted to double the size of a, you could do the following:

如果你想让a的大小增加一倍,你可以这样做:

a = grow( letters,  21);

See...

看到……

https://github.com/RichardHightower/boon/blob/master/src/main/java/org/boon/core/primitive/Byt.java

https://github.com/RichardHightower/boon/blob/master/src/main/java/org/boon/core/primitive/Byt.java

    byte[] letters =
            arrayOfByte(500);

    assertEquals(
            500,
            len(letters)
    );

Create

创建

    byte[] letters =
            array((byte)0, (byte)1, (byte)2, (byte)3);

    assertEquals(
            4,
            len(letters)
    );

Index

指数

    byte[] letters =
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d');

    assertEquals(
            'a',
            idx(letters, 0)
    );


    assertEquals(
            'd',
            idx(letters, -1)
    );


    assertEquals(
            'd',
            idx(letters, letters.length - 1)
    );


    idx(letters, 1, (byte)'z');

    assertEquals(
            (byte)'z',
            idx(letters, 1)
    );

Contains

包含

    byte[] letters =
            array((byte)'a',(byte) 'b', (byte)'c', (byte)'d');


    assertTrue(
            in((byte)'a', letters)
    );

    assertFalse(
            in((byte)'z', letters)
    );

Slice:

片:

    byte[] letters =
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d');


    assertArrayEquals(
            array((byte)'a', (byte)'b'),
            slc(letters, 0, 2)
    );

    assertArrayEquals(
            array((byte)'b', (byte)'c'),
            slc(letters, 1, -1)
    );

    //>>> letters[2:]
    //['c', 'd']
    //>>> letters[-2:]
    //['c', 'd']

    assertArrayEquals(
            array((byte)'c', (byte)'d'),
            slc(letters, -2)
    );


    assertArrayEquals(
            array((byte)'c', (byte)'d'),
            slc(letters, 2)
    );


    //>>> letters[:-2]
    //     ['a', 'b']
    assertArrayEquals(
            array((byte)'a', (byte)'b'),
            slcEnd(letters, -2)
    );


    //>>> letters[:-2]
    //     ['a', 'b']
    assertArrayEquals(
            array((byte)'a',(byte) 'b'),
            slcEnd(letters, 2)
    );

Grow

成长

    byte[] letters =
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e');

    letters = grow( letters,  21);


    assertEquals(
            'e',
            idx(letters, 4)
    );


    assertEquals(
            'a',
            idx(letters, 0)
    );




    assertEquals(
            len(letters),
            26
    );


    assertEquals(
            '\0',
            idx(letters, 20)
    );

Shrink:

萎缩:

    letters =  shrink ( letters, 23 );

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c'),
            letters

    );

Copy:

复制:

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e'),
            copy(array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e'))

    );

Add:

添加:

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'),
            add(array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e'), (byte)'f') );

The add actually adds them together by using System.arraycopy (considering Unsafe, but not yet).

添加实际上是通过使用系统将它们加在一起。arraycopy(考虑不安全,但还没有)。

Add one array to another:

将一个数组添加到另一个数组:

    assertArrayEquals(
            array(     (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'),
            add( array((byte)'a', (byte)'b', (byte)'c', (byte)'d'), array((byte)'e', (byte)'f') )

    );

Insert:

插入:

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g'),
            insert( array((byte)'a', (byte)'b', (byte)'d', (byte)'e', (byte)'f', (byte)'g'), 2, (byte)'c' )

    );

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g'),
            insert( array((byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g'), 0, (byte)'a' )

    );

    assertArrayEquals(
            array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g'),
            insert( array((byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'g'), 5, (byte)'f' )

    );

Here is a peek at a few of the methods:

以下是一些方法:

public static byte[] grow(byte [] array, final int size) {
    Objects.requireNonNull(array);

    byte [] newArray  = new byte[array.length + size];
    System.arraycopy(array, 0, newArray, 0, array.length);
    return newArray;
}



public static byte[] grow(byte [] array) {
    Objects.requireNonNull(array);

    byte [] newArray  = new byte[array.length *2];
    System.arraycopy(array, 0, newArray, 0, array.length);
    return newArray;
}


public static byte[] shrink(byte[] array, int size) {
    Objects.requireNonNull(array);

    byte[] newArray = new byte[array.length - size];

    System.arraycopy(array, 0, newArray, 0, array.length-size);
    return newArray;
}




public static byte[] copy(byte[] array) {
    Objects.requireNonNull(array);
    byte[] newArray = new byte[array.length];
    System.arraycopy(array, 0, newArray, 0, array.length);
    return newArray;
}


public static byte[] add(byte[] array, byte v) {
    Objects.requireNonNull(array);
    byte[] newArray = new byte[array.length + 1];
    System.arraycopy(array, 0, newArray, 0, array.length);
    newArray[array.length] = v;
    return newArray;
}

public static byte[] add(byte[] array, byte[] array2) {
    Objects.requireNonNull(array);
    byte[] newArray = new byte[array.length + array2.length];
    System.arraycopy(array, 0, newArray, 0, array.length);
    System.arraycopy(array2, 0, newArray, array.length, array2.length);
    return newArray;
}



public static byte[] insert(final byte[] array, final int idx, final byte v) {
    Objects.requireNonNull(array);

    if (idx >= array.length) {
        return add(array, v);
    }

    final int index = calculateIndex(array, idx);

    //Object newArray = Array.newInstance(array.getClass().getComponentType(), array.length+1);
    byte [] newArray = new byte[array.length+1];

    if (index != 0) {
        /* Copy up to the location in the array before the index. */
        /*                 src     sbegin  dst       dbegin   length of copy */
        System.arraycopy( array,   0,      newArray, 0,       index );
    }


    boolean lastIndex = index == array.length -1;
    int remainingIndex = array.length - index;

    if (lastIndex ) {
        /* Copy the area after the insert. Make sure we don't write over the end. */
        /*                 src  sbegin   dst       dbegin     length of copy */
        System.arraycopy(array, index,   newArray, index + 1, remainingIndex );

    } else {
        /* Copy the area after the insert.  */
        /*                 src  sbegin   dst       dbegin     length of copy */
        System.arraycopy(array, index,   newArray, index + 1, remainingIndex );

    }

    newArray[index] = v;
    return  newArray;
}


public static byte[] insert(final byte[] array, final int fromIndex, final byte[] values) {
    Objects.requireNonNull(array);

    if (fromIndex >= array.length) {
        return add(array, values);
    }

    final int index = calculateIndex(array, fromIndex);

    //Object newArray = Array.newInstance(array.getClass().getComponentType(), array.length+1);
    byte [] newArray = new byte[array.length +  values.length];

    if (index != 0) {
        /* Copy up to the location in the array before the index. */
        /*                 src     sbegin  dst       dbegin   length of copy */
        System.arraycopy( array,   0,      newArray, 0,       index );
    }


    boolean lastIndex = index == array.length -1;

    int toIndex = index + values.length;
    int remainingIndex = newArray.length - toIndex;

    if (lastIndex ) {
        /* Copy the area after the insert. Make sure we don't write over the end. */
        /*                 src  sbegin   dst       dbegin     length of copy */
        System.arraycopy(array, index,   newArray, index + values.length, remainingIndex );

    } else {
        /* Copy the area after the insert.  */
        /*                 src  sbegin   dst       dbegin     length of copy */
        System.arraycopy(array, index,   newArray, index + values.length, remainingIndex );

    }

    for (int i = index, j=0; i < toIndex; i++, j++) {
        newArray[ i ] = values[ j ];
    }
    return  newArray;
}

More....

更多....