2015-07-16 4 views
3

Недавно я создал оболочку для чтения и записи данных в массив byte. Чтобы сделать это, я был используя ArrayList<Byte>, но мне было интересно, если это самое ЭФФЕКТИВНЫЙ способ сделать это, потому что:Java - ByteBuffer или ArrayList <Byte>?

  • addAll() не работает с byte массивами (даже с использованием Arrays.asList(), которая возвращает я List<Byte[]>). Чтобы исправить это, я просто зацикливаюсь и добавляю byte в каждом цикле, но я предполагаю, что это предполагает множество вызовов функций, и поэтому у него есть стоимость исполнения.
  • То же самое происходит при получении byte[] от ArrayList. Я не могу отличить от Byte[] до byte[], поэтому я должен использовать для этого цикл.
  • Я полагаю, что хранение байта вместо байта использует больше памяти.

Я знаю ByteArrayInputStream и ByteArrayOutputStream может быть использован для этого, но она имеет некоторые inconvenients:

  • Я хотел реализовать методы для чтения различных типов данных в другом порядке байт (например, readInt, readLEInt , readUInt и т. Д.), Тогда как эти классы могут читать или записывать байт или массив байтов. Это не проблема, потому что я могу исправить это в обертке. Но здесь возникает вторая проблема.
  • Я хотел иметь возможность писать и читать одновременно, потому что я использую это для распаковки некоторых файлов. И поэтому для создания обертки для этого мне нужно будет включить как ByteArrayInputStream, так и ByteArrayOutputStream. Я не знаю, могли ли они быть синхронизированы каким-либо образом, или мне пришлось бы писать все данные одного из них каждый раз, когда я писал обертке.

И вот, вот мой вопрос: будет ли использование ByteBuffer более эффективным? Я знаю, что вы можете взять integers, floats и т. Д., Даже будучи в состоянии изменить порядок байтов. Мне было интересно, есть ли реальное изменение производительности между использованием ByteBuffer и ArrayList<Byte>.

+2

'ArrayList ' не кажется хорошей идеей. – biziclop

+0

Если вам нужен буфер с динамическим размером, посмотрите на мой комментарий, используйте ByteArrayOutputStream, расширьте его и используйте файлы buf и count, чтобы сделать некоторые быстрые методы чтения. Он имеет приключения, что он имеет динамический размер; –

ответ

3

Определенно ByteBuffer или ByteArrayOutputStream. В вашем случае ByteBuffer кажется штрафом. Осмотрите Javadoc, так как он имеет хорошие методы, Для putInt/GetInt и такой, вы можете захотеть установить порядок (из этих 4 байта)

byteBuffer.order(ByteBuffer.LITTLE_ENDIAN); 

с файлами можно использовать getChannel() или варианты, а затем использовать MappedByteBuffer.

ByteBuffer может обернуть массив байтов или выделить.

+0

Хорошо, будет использовать ByteBuffer, тогда, спасибо! – Emd4600

1

Помните, что каждый объект имеет связанные с ним служебные данные, включая бит памяти на объект и сбор мусора, когда он выходит из сферы действия.

Использование List<Byte> будет означать создание/сбор мусора, собирающего объект за один байт, что очень расточительно.

0

ByteBuffer - это класс оболочки вокруг байтового массива, он не имеет динамического размера, такого как ArrayList, но он потребляет меньше памяти на каждый байт и быстрее. Если вы знаете размер, который вам нужен, тогда используйте ByteBuffer, если вы этого не сделаете, тогда вы можете использовать ByteArrayOutputStream (и, возможно, обернутый ObjectOutputStream, он имеет некоторые методы для записи разных видов данных). Чтобы прочитать данные, которые вы написали в ByteArrayOutputStream, вы можете расширить ByteArrayOutputStream, а затем вы можете получить доступ к полям buf [] и подсчитать, эти поля защищены, поэтому вы можете получить к ним доступ из класса расширения, это выглядит так:

public class ByteArrayOutputStream extends OutputStream { 

    /** 
    * The buffer where data is stored. 
    */ 
    protected byte buf[]; 
    /** 
    * The number of valid bytes in the buffer. 
    */ 
    protected int count; 
... 
} 


public class ReadableBAOS extends ByteArrayOutputStream{ 
    public byte readByte(int index) { 
     if (count>index) { 
      throw new IndexOutOfBoundsException(); 
     } 
     return buf[index]; 
    } 
} 

, поэтому вы можете сделать некоторые методы в своем расширяющемся классе, чтобы прочитать несколько байтов из базового буфера без необходимости делать копию своего содержимого каждый раз, как это делает метод byByteArray().

+0

'ByteBuffer' не является классом-оболочкой для' byte [] ', хотя вы можете обернуть его' byte [] '. Если вы используете 'allocateDirect', вы получите собственную память вместо' byte [] '. – Kayaman

+0

Интересно, спасибо! – Emd4600

Смежные вопросы