Question

I have used the ByteArrayOutputStream which is very useful but for my needs the limits are too great (ie I am dealing with numbers in the range +-32,768)

Here is the code where I would use it:

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

However the ByteArrayInputStream does not allow for values over 127 or under 128. Is there an equivalent ShortArrayOutputStream that allows shorts? Or do I have to make one myself somehow?

Was it helpful?

Solution

Yes, Use the DataOutputStream:

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

dos.writeShort(val);

This works even on embedded java devices with low java version 1.3

To read in use:

ByteArrayInputStream and DataInputStream dis, and dis.readShort():

...
byte[] bytes = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
DataInputStream dis = new DataInputStream(bis);
short val = dis.readShort();

OTHER TIPS

You can wrap the ByteArrayOutputStream into DataOutputStream:

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

dataOutputStream.writeShort(someShortValue);

What do you want to do?

Write out short data to a byte array?

Then wrap your byte array output stream with a DataOutputStream which has methods to writeShort(), writeInt() etc. Warning. I think the endian of DataOutputStream is BIG endian so if you want to use little endian you either have to write it yourself or use the other option:

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

dataout.writeShort(shortValue);

Write a short[]

the easiest is to create a ByteBuffer, then use the asShortBuffer() method to view it as a ShortBuffer. the ShortBuffer has a put(short) and put(short[]);

If you want to write out the short data in Little endian, ByteBuffer has a method asOrder(ByteOrder) which can change the endian of the data it is reading or writing.

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

getting data out from buffers is annoying. There are optional array() methods but not all buffer impelmentations support them so you have to do the following:

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

Combination of both to use a ShortBuffer on an unknown input size

If you don't know how many bytes you will write, and you don't have a reasonable, max length, then you may need to do a combination of both options. First, use option #1 to dynamically grow a byte buffer by writing shorts to it. Then convert the byte[] to a short[] with the 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);

It's not pretty and uses 2x the memory since you make a copy of the array.

Create a ObjectOutputStream. This has a writeShort (http://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html#writeShort(int)) method.

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeShort(123);
...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top