ByteArrayOutputStream для шортов вместо байтов

1

Я использовал ByteArrayOutputStream, который очень полезен, но для моих потребностей пределы слишком велики (т.е. я имею дело с числами в диапазоне +-32, 768)

Вот код, где я буду использовать его:

ByteArrayOutputStream leftStream = new ByteArrayOutputStream();
ByteArrayOutputStream rightStream = new ByteArrayOutputStream();

while (din.read(temp, 0, 4) != -1) {
    if (decodedFormat.getChannels() == 2) {
       leftStream.write(temp[1] * 256 + temp[0]);
       rightStream.write(temp[3] * 256 + temp[2]);
    }
}

byte[] left = leftStream.toByteArray();
byte[] right = rightStream.toByteArray();

Однако ByteArrayInputStream не позволяет использовать значения более 127 или менее 128. Есть ли эквивалентный ShortArrayOutputStream, который позволяет использовать шорты? Или я должен сам это сделать?

Теги:
short
bytearrayoutputstream

4 ответа

2
Лучший ответ

Да, используйте DataOutputStream:

ByteArrayOuputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);

dos.writeShort(val);

Это работает даже на встроенных java-устройствах с низкой версией java версии 1.3

Для чтения:

ByteArrayInputStream и DataInputStream dis и dis.readShort():

...
byte[] bytes = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
DataInputStream dis = new DataInputStream(bis);
short val = dis.readShort();
  • 0
    Спасибо, если я напишу шорты со значениями больше 128, то toByteArray точно не пропустит эти шорты?
  • 0
    Сокращение составляет 2 байта в Java: от -32767 до 32768 в Java. так что именно то, что вы пишете, читается в. вы должны прочитать это в том же порядке, в котором вы пишете. Если все шорты, то хорошо. Вы можете смешивать байты с шортами и int, но использовать порядок smae при чтении в.
Показать ещё 2 комментария
1

Вы можете обернуть ByteArrayOutputStream в DataOutputStream:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);

dataOutputStream.writeShort(someShortValue);
  • 0
    Как можно получить массив short [] из этого потока? Как какой- toShortArray() метод toShortArray() ?
  • 0
    @ Бьется с readShort () конечно, но из DataInputStream ()
Показать ещё 6 комментариев
1

Что ты хочешь делать?

Вывести короткие данные в массив байтов?

Затем заверните выходной поток байтового массива с помощью DataOutputStream, который имеет методы writeShort(), writeInt() и т.д. Предупреждение. Я думаю, что endian DataOutputStream является BIG endian, поэтому, если вы хотите использовать маленький endian, вам либо нужно написать его самостоятельно, либо использовать другой вариант:

ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
DataOutputStream dataout = new DataOutputStream(byteOut)

dataout.writeShort(shortValue);

Напишите короткий []

проще всего создать ByteBuffer, а затем использовать метод asShortBuffer() чтобы просмотреть его как ShortBuffer. ShortBuffer имеет put(short) и put (short []);

Если вы хотите выписать короткие данные в Little endian, ByteBuffer имеет метод asOrder(ByteOrder) который может изменять asOrder(ByteOrder) данных, которые он читает или записывает.

//NOTE length should be 2* num shorts since we allocate in bytes
ByteBuffer buf = ByteBuffer.allocate(length);

ShortBuffer shortBuf = buf.asShortBuffer();
shortBuf.put(shortValue);
shortBuf.put(shortArray);

получение данных из буферов вызывает раздражение. Существуют дополнительные методы array() но не все имплантации буферов поддерживают их, поэтому вам нужно сделать следующее:

//once all data written to buffer
shortBuf.flip();
short[] dataOut = new short[shortBuf.remaining()];
shortBuf.get(dataOut);

Комбинация как для использования ShortBuffer при неизвестном размере ввода

Если вы не знаете, сколько байтов вы напишете, и у вас нет разумной максимальной длины, вам может понадобиться комбинация обоих вариантов. Во-первых, используйте опцию # 1 для динамического роста байтового буфера путем написания коротких сообщений. Затем преобразуйте байт [] в короткий [] с помощью ShortBuffer.

 ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
DataOutputStream dataout = new DataOutputStream(byteOut)

dataout.writeShort(shortValue);
...

ShortBuffer buf =ByteBuffer.wrap(byteOut.toByteArray())
                           .asShortBuffer();

int length = buf.remaining();
short[] asShorts = new short[length];
buf.get(asShorts);

Это не очень хорошо и использует 2x память, так как вы делаете копию массива.

  • 0
    Не могли бы вы опубликовать пример, как использовать второй вариант?
  • 0
    Это не самый простой вариант. Но на ПК гораздо быстрее, чем решение dataOutputStream. Маленький и большой порядок байтов никогда не был точкой в его вопросе
Показать ещё 7 комментариев
-2

Создайте ObjectOutputStream. У этого есть метод writeShort (http://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html#writeShort(int)).

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeShort(123);
...
  • 0
    Объект OutputStream является избыточным, поскольку предполагается, что он используется для сериализации объектов, а не для записи примитивных массивов.
  • 0
    и он использует огромное количество памяти, и медленно, как ад.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню