سؤال

أقوم بإنشاء مصفوفة من البايتات في جافا ولا أعرف المدة التي ستستغرقها المصفوفة.

أريد بعض الأدوات مثل StringBuffer في Java والتي يمكنك فقط الاتصال بـ .append(byte b) أو .append(byte[] buf) وجعلها مخزنة مؤقتًا لكل وحدات البايت الخاصة بي وتعيد إليّ مصفوفة بايت عندما أنتهي.هل هناك فئة تفعل للبايت ما يفعله StringBuffer للسلاسل؟لا يبدو أن فئة ByteBuffer هي ما أبحث عنه.

هل لدى أي شخص حل جيد؟

هل كانت مفيدة؟

المحلول

ByteArrayOutputStream . يمكنك استخدام write( byte[] ) وانها سوف تنمو حسب الحاجة.

نصائح أخرى

وفقط لتمديد الإجابة السابقة، يمكنك استخدام ByteArrayOutputStream وانها public void write(byte[] b, int off, int len) طريقة، حيث المعلمات:

<اقتباس فقرة>   

وب - البيانات

     

وقبالة - بدء الإزاحة في البيانات

     

وليون - عدد البايتات لكتابة

إذا كنت ترغب في استخدامه بمثابة "باني بايت" وإدراج بايت بواسطة بايت، يمكنك استخدام هذا:

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

وبعد ذلك يمكنك استخدام أسلوب baos.toString() لتحويل مجموعة إلى سلسلة. ميزة هي عندما كنت في حاجة لاقامة ترميز الإدخال، يمكنك ببساطة استخدام أي بمعنى:.

baos.toString("Windows-1250")

لقد كتبت واحدة سهلة الاستخدام حقًا وتتجنب الكثير من نسخ المخزن المؤقت لصفيف البايت.

لديها طريقة واحدة تسمى الإضافة.

يمكنك إضافة سلاسل، بايت، بايت، طويل، int، مزدوج، تعويم، قصير، وأحرف إليها.

واجهة برمجة التطبيقات (API) سهلة الاستخدام وآمنة إلى حد ما.لا يسمح لك بنسخ المخزن المؤقت ولا يشجع على وجود قارئين.

يحتوي على وضع التحقق من الحدود ووضع أعرف ما أفعله دون التحقق من الحدود.

يعمل وضع التحقق من الحدود على نموه تلقائيًا حتى لا يكون هناك أي متاعب.

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

فيما يلي دليل كامل خطوة بخطوة حول كيفية استخدامه.إنه على جيثب.

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 بالضبط، فأنا أقول...يا..أعرف بالضبط الحجم الذي يمكن أن ينمو إليه ولن يتجاوز هذا الرقم أبدًا، وإذا حدث ذلك... يمكنك ضربي على رأسي بكيس من الصخور!

التالي يضربك على رأسك بكيس من الصخور!يرمي استثناء!

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

إنه يعمل مع كثافة العمليات.

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

يعمل مع شار.

    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، فإنه يوفر لك المخزن المؤقت الخاص به.هذه هي حالتي الداخلية، يمكنك الحصول عليها، لكنني سأقوم بضبطها على قيمة فارغة حتى لا يستخدمها أي شخص آخر.

هذا جيد.ما عليك سوى إنشاء مثيل آخر إذا كنت متأكدًا من أن مثيلًا واحدًا فقط في كل مرة يستخدم المخزن المؤقت (البايت []).

يمكنك حتى استخدام المخزن المؤقت الذي كنت تستخدمه للتو كما في

ByteBuf buf2 = new ByteBuf.create(bytes); 

وذلك لأنه لا يتم نسخ أي مخزن مؤقت.يكتب ByteBuf إلى المخزن المؤقت الذي تقدمه له.إذا كنت تريد إعطاء نسخة أخرى إلى ByteBuf، فافعل هذا:

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

هذه نعمة بعد كل شيء.:)

تعال وتحقق من نعمة.يمكنك الحصول على الفئة المذكورة أعلاه وidx وidxInt وidxLong مجانًا!

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

ودعونا نرى. وهناك فئة ByteBuffer في جاوة.

http://docs.oracle.com/ javase / 7 / مستندات / المعهد / جافا / 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 [] a = ...
byte [] b = ...
byte [] c = ...

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

وهذا من شأنه أن يوفر لك جميع محتويات ب، ج بعد محتويات ل.

إذا كنت تريد أن تنمو بنسبة 21، هل يمكن أن تفعل ما يلي:

a = grow( letters,  21);

إذا أردت أن يتضاعف حجم، هل يمكن أن تفعل ما يلي:

a = grow( letters,  21);

وانظر ...

الشبكي: //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;
}

وأكثر ....

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top