3

So the first four bytes of my ByteArrayOutputStream contain the length of a header in my stream. I need to remove that header from the stream and go on with my business.

ByteArrayOutputStream oStream = new ByteArrayOutputStream();
/* populate ByteArrayOutputStream */

//grab first int
int headerLength = oStream.toByteArray()[4];

//remove headerLength
String newString = oStream.toString().substring(jsonLength, oStream.size());
oStream.write(newString.getBytes());

I don't think this is the proper way to go about this though, does anyone have any suggestions?

Grammin
  • 11,808
  • 22
  • 80
  • 138
  • 9
    Why do you write them to the stream if you need to remove them later? Just don't write them in the first place. – JB Nizet Jun 27 '12 at 13:15
  • @JB Nizet - I actually do need them I just left out a lot of code to make things easier to understand. Once I use them though I need to remove them. – Grammin Jun 27 '12 at 13:19
  • 3
    @Grammin: You haven't made things easier to understand - you've made them completely incomprehensible. It's really not clear what you're trying to do at all. – Jon Skeet Jun 27 '12 at 13:22
  • 2
    The goal of a ByteArrayOutputStream is to generate a byte array. If you don't want the header length in the final byte array, you shouldn't write it to the output stream. If you want the header length in the byte array, then there is nothing to remove. What are you actually trying to achieve? – JB Nizet Jun 27 '12 at 13:26
  • 1
    When you are using the result of the OutputStream, you can skip the fiirst N byte then. e.g. `write(oStream.toByteArray(), 4, length-4)` – Peter Lawrey Jun 27 '12 at 13:26

2 Answers2

4

The simple answer is to write the 4 bytes in the first place ... if you can achieve that.

Another answer would be to write a custom FilterOutputStream subclass that ignores the first 4 bytes written.

Yet another is to extract the bytes, and then use one of the Arrays.copy methods to create a new byte array containing the "slice" of the original that you require; e.g.

byte[] subarray = Arrays.copyOfRange(original, 4, original.length - 4);

Or if your application can cope with an "undefined" area at the end of the byte array, you can do something like this:

System.arraycopy(array, 4, array.length - 4, array, 0);  // YMMV - check javadoc

Finally, depending on what you are using the byte array for, there's a good chance you can ignore the first 4 bytes without removing them. For instance, you can do this when writing bytes to a stream, when creating a string from bytes, when copying bytes to a ByteBuffer, and so on.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

There is no possible way to do what you're asking.
You will have to invent your own OutputStream with a remove method.
I suggest that this OutputStream will accept as parameter another OutputStream , and when you perform write, it will accumulate the bytes (using similar technique to what ByteArrayOutputStream does)
Upon removal, you will have access to your internal data structure (let's say array) and will code a removal algorithm (for example - removal of M entries from an array, starting at position N ).
Another option is to extend ByteArrayOutputStream - I just checked its code, and turns out the internal buffer is protected (the field is named "buf") - so implement my above suggestion on this . The code should look like (not giving the full code):

public class MyByteArrayOutputStream extends ByteArrayOutputStream {
   //Implement all the CTORs

   public int remove (int startFrom, int length)  {
       //Implement removal algorithm on array on the field "buf" 
       //return the number of removed elements
   }
}
Yair Zaslavsky
  • 4,091
  • 4
  • 20
  • 27