سؤال

أحتاج إلى أن أكون قادرًا على تحويل صفائف البايت إلى/من صفائف النوع البدائي الأخرى، ولكن بدلاً من الإرسال، أحتاج اكتب الضرب. المصطلح الصحيح للنسخة الخام بدون صب؟

اعتقدت أنه سيكون من الممكن القيام بما يلي:

// idea: byte[12] -> int[3], and int[3] -> byte[12]

int[] ints;

ByteBuffer bb = ByteBuffer.wrap(
    new byte[]{ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3 });
IntBuffer ib = bb.asIntBuffer();

ints = ib.array(); // java.lang.UnsupportedOperationException
ints = ib.duplicate().array(); // java.lang.UnsupportedOperationException

لسوء الحظ، يبدو ذلك bb.asIntBuffer() يكون لا إنشاء IntBuffer جديد عن طريق نسخ المحتوى "bitwise" أو "raw"، ولكنه ينشئ "عرضًا" جديدًا على ByteBuffer الموجود.لهذا .array() يهدف إلى الفشل.

لقد قمت بالتصفح في مصادر JDK، ووجدت عددًا قليلًا من الفئات، التي تستخدمها كل هذه الفئات العازلة و كان أفعل الأشياء التي أحتاجها، ولكنها داخلية (مثل class Unsafe).

بينما أعتقد أنه يمكن تحقيق هدفي من خلال تغليف المخزن المؤقت للبايت في البعض ObjectInputStream وقراءة القيم البدائية بواسطة .readInt(), ، أعتقد أنه سيكون حلاً فوضويًا وبطيئًا.

إذن، هل هناك أي حلول أخرى ممكنة؟ بدون القيام بعمليات حسابية سحرية من النوع البدائي (التحويل، والتحقق من النهايات، ...)؟

ملحوظة:أحتاج إلى كلا الاتجاهين:البايت[12] -> int[3]، و int[3] -> البايت[12]

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

المحلول

وفقًا لـ javadoc، تُرجع array() [1] مصفوفة دعم المخزن المؤقت وهي المصفوفة التي تحددها من خلال استدعاء Wrap() [2].

ومن ثم، يجب عليك إنشاء مجموعة جديدة بالنوع المطلوب.ولكن لا يزال من الممكن التعامل مع العمليات الحسابية عبر فئات Buffer.

ByteBuffer bb = ByteBuffer.wrap(new byte[]{ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3 });
IntBuffer ib = bb.asIntBuffer();

int[] intArray = new int[ib.limit()];
ib.get(intArray);

يتطلب الرجوع للخلف القليل من الحساب بنفسك.

ByteBuffer newBb = ByteBuffer.allocate(intArray.length*4);
newBb.asIntBuffer().put(intArray);
byte[] byteArray = newBb.array();

يرى:

[1] http://java.sun.com/javase/6/docs/api/Java/nio/ByteBuffer.html#array%28%29

[2] http://java.sun.com/javase/6/docs/api/Java/nio/ByteBuffer.html#wrap%28byte[]%29

نصائح أخرى

شكرا جزيلا ل com.wierob للحصول على الكود الخاص به لتحويل البايت[]->int[]!

لقد لعبت قليلاً للحصول على الاتجاه المعاكس للعمل.

1) واجهة برمجة التطبيقات

// byte[] -> int[]
public static int[] punnedToInteger(byte[] in){
    ByteBuffer bb = ByteBuffer.wrap(in);
    IntBuffer pb = bb.asIntBuffer();

    int[] out = new int[pb.limit()];
    pb.get(out);

    return out;
}

// int[] -> byte[]
public static byte[] punnedFromInteger(int[] in){
    byte[] out = new byte[in.length * Integer.SIZE / Byte.SIZE];
    ByteBuffer bb = ByteBuffer.wrap(out);

    for(int i=0; i<in.length; ++i){
        bb.putInt(in[i]);
    }

    return out;
}

2) حالة الاختبار

{
    byte[] bytes = new byte[]{ 0,0,0,1, 0,0,1,0, 0,1,0,0, 1,0,0,0 };
    int[] ints = punnedToInteger(bytes);
    System.out.println(Arrays.toString(bytes));
    System.out.println(Arrays.toString(ints));
    System.out.println();
}
{
    int[] ints = new int[]{ 1, 256, 65536, 16777216 };
    byte[] bytes = punnedFromInteger(ints);
    System.out.println(Arrays.toString(ints));
    System.out.println(Arrays.toString(bytes));
    System.out.println();
}

3) الإخراج

[0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0]
[1, 256, 65536, 16777216]

[1, 256, 65536, 16777216]
[0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0]
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top