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!
让我们来看看。 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; }
更多….