program story

Java에서 길이를 알 수없는 바이트 배열

inputbox 2020. 11. 11. 20:00
반응형

Java에서 길이를 알 수없는 바이트 배열


Java에서 바이트 배열을 구성하고 있는데 배열이 얼마나 오래 걸릴지 모르겠습니다.

.append (byte b) 또는 .append (byte [] buf)를 호출하고 모든 바이트를 버퍼링하고 완료되면 바이트 배열을 반환 할 수있는 Java의 StringBuffer와 같은 도구를 원합니다. StringBuffer가 문자열에 대해 수행하는 작업을 바이트로 수행하는 클래스가 있습니까? ByteBuffer 클래스가 내가 찾고있는 것 같지 않습니다.

누구든지 좋은 해결책이 있습니까?


시도해보십시오 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()메서드를 사용 하여 배열을 문자열로 변환 할 수 있습니다 . 장점은 입력 인코딩을 설정해야 할 때 다음과 같이 간단히 사용할 수 있다는 것입니다.

baos.toString("Windows-1250")

나는 정말 사용하기 쉽고 많은 바이트 배열 버퍼 복사를 피하는 것을 작성했습니다.

add라는 하나의 메소드가 있습니다.

string, bytes, byte, long, int, double, float, short 및 chars를 추가 할 수 있습니다.

API는 사용하기 쉽고 다소 안전합니다. 그것은 당신이 버퍼를 복사하는 것을 허용하지 않으며 두 명의 독자를 갖는 것을 촉진하지 않습니다.

경계 검사 모드와 경계 검사가없는 I KNOW WHAT I AM DOING MODE가 있습니다.

경계 검사 모드는 자동으로 확장되므로 번거 로움이 없습니다.

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

다음은 사용 방법에 대한 완전한 단계별 가이드입니다. github에 있습니다.

Java Boon-ByteBuilder와 같은 자동 확장 가능한 바이트 버퍼

자동으로 확장되는 사용하기 쉬운 버퍼 어레이를 원했거나 고정 크기를 지정하고 항목을 추가 할 수있는 방법을 원하십니까? 나는 가지고있다. 나도 하나 썼다.

보세요 .. 문자열을 쓸 수 있습니다 (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 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());

create exact를 사용하면 ... 헤이 .. 얼마나 커질 수 있는지 정확히 알고 있으며이 숫자를 넘지 않을 것입니다. 만약 그렇다면 ... 자루로 머리를 때릴 수 있습니다. 바위!

다음은 바위 자루로 머리를 때립니다! 예외를 던졌습니다 !!!!

    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;

이제 우리는 모든 것을 다시 읽을 수 있는지 확인합니다.

    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로 설정할 것입니다.

괜찮아요. 한 번에 하나의 인스턴스 만 버퍼 (바이트 [])를 사용하고 있다고 확신하는 경우 다른 인스턴스를 만드십시오.

방금 사용한 버퍼를 사용할 수도 있습니다.

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

연속적인 바이트 시퀀스를 바이트 배열에서 하드웨어 버퍼로 전송하는 대량 메서드가 있습니다. 트릭을 할 것입니다.

또한 바이트 버퍼에 대해 byte [] 및 기타 프리미티브를 읽고 쓰는 절대 및 상대 get 및 put 메소드가 있습니다.

또한 바이트 버퍼를 압축, 복제 및 분할하는 방법도 있습니다.

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

이렇게하면 a의 내용 뒤에 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)
    );

창조하다

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

더....

참고 URL : https://stackoverflow.com/questions/664389/byte-array-of-unknown-length-in-java

반응형