java中未知长度的字节数组

我在java中构造一个字节数组,我不知道数组将会是多久。

我想要一些像Java的StringBuffer这样的工具,你可以直接调用.append(byte b)或者.append(byte [] buf),并且缓冲所有的字节,当我完成的时候返回给我一个字节数组。 是否有一个String对String的作用是什么? 它看起来不像ByteBuffer类是我正在寻找的。

任何人有一个好的解决scheme

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

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

b – 数据

off – 数据中的起始偏移量

len – 要写入的字节数

如果你想用它作为“字节生成器”并逐字节地插入,你可以使用这个:

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

然后你可以使用baos.toString()方法将数组转换为string。 好处是当你需要设置input的编码时,你可以简单地使用ie:

 baos.toString("Windows-1250") 

我写了一个非常容易使用,并避免了大量的字节数组缓冲区复制。

它有一个叫做add的方法。

你可以添加string,字节,字节,长,整型,双精度型,浮点型,短型和字符。

该API易于使用,并且有些失败。 它不允许你复制周围的缓冲区,不推动有两个读者。

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

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

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

这是一个完整的一步一步的指导如何使用它。 它在github上。

Java Boon – 像ByteBuilder一样的可自动生长的字节缓冲区

你有没有想过一个易于使用的缓冲区arrays自动增长和/或你可以给它一个固定的大小,只是添加的东西呢? 我有。 我也写了一个。

看看..我可以写string(它将它们转换为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"); 

然后,我可以读取缓冲区中的string:

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

我从来不需要设置数组的大小。 它将根据需要以高效的方式自动增长。

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

  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()); 

如果我使用确切的,那么我说…嘿,我知道它到底有多大,它永远不会超过这个数字,如果它确实… …你可以用麻袋打我的头岩石!

下面用一袋石头击中你的头! 抛出一个例外!

  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"); 

它适用于双打。

  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"); 

它适用于浮动。

  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"); 

它与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"); 

它适用于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'"); 

它适用于短。

  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"); 

它甚至与字节一起工作。

  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"); 

您可以将各种原语添加到您的字节数组中。

  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; 

现在我们只是validation我们可以读回所有的东西。

  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"); 

一旦你打电话

  byte[] bytes = buf.readAndReset() 

那么你就是说你已经完成了ByteBuffer!

一旦你要求这些字节,它将变成无用的,因为它将内部字节数组设置为空。

当你调用readAndReset时,它会给你它的缓冲区。 这里是我的内部状态,你可以拥有它,但是我将把它设置为null,所以没人使用它。

没关系。 如果您确定一次只有一个实例正在使用缓冲区(byte []),则只需创build另一个实例。

你甚至可以使用你刚刚使用的缓冲区

 ByteBuf buf2 = new ByteBuf.create(bytes); 

这是因为没有缓冲区被复制。 ByteBuf写入你给它的缓冲区。 如果你想给ByteBuf另外一个副本,那么这样做:

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

毕竟这是好事。 🙂

快来看看恩。 你可以免费获得上面的课程和idx,以及idxInt和idxLong!

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

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

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

它具有批量方法,可以将连续的字节序列从字节数组传输到硬件缓冲区。 它会做的伎俩。

它也有绝对的和相对的读取和写入字节缓冲区的字节[]和其他原语的方法。

它也有压缩,复制和分割字节缓冲区的方法。

 // 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) 

它也有一个批量放置数组,这是非常接近你要求的追加:

 public final ByteBuffer put(byte[] src) 

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

我写了自己的小库来操作字节数组。 🙂

你可以像这样添加它们

 byte [] a = ... byte [] b = ... byte [] c = ... a = add(a, b); a = add(a, c); 

这会给你所有的内容b和c之后的内容。

如果你想增长一个21,你可以做到以下几点:

 a = grow( letters, 21); 

如果您想将a的大小加倍,则可以执行以下操作:

 a = grow( letters, 21); 

看到…

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

  byte[] letters = arrayOfByte(500); assertEquals( 500, len(letters) ); 

创build

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

指数

  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) ); 

包含

  byte[] letters = array((byte)'a',(byte) 'b', (byte)'c', (byte)'d'); assertTrue( in((byte)'a', letters) ); assertFalse( in((byte)'z', letters) ); 

片:

  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) ); 

增长

  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) ); 

收缩:

  letters = shrink ( letters, 23 ); assertArrayEquals( array((byte)'a', (byte)'b', (byte)'c'), letters ); 

复制:

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

加:

  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') ); 

添加实际上通过使用System.arraycopy(考虑不安全,但尚未)将它们加在一起。

添加一个数组到另一个:

  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') ) ); 

插:

  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' ) ); 

这里是一些方法偷看:

 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; } 

更多….