File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes Reading variable size buffer into an byte array Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login


Win a copy of The Mikado Method this week in the Agile and other Processes forum!
JavaRanch » Java Forums » Java » Java in General
Reply Bookmark "Reading variable size buffer into an byte array" Watch "Reading variable size buffer into an byte array" New topic
Author

Reading variable size buffer into an byte array

Mike Bates
Ranch Hand

Joined: Sep 19, 2009
Posts: 81
I am reading a buffer from a serial port that is consistently variable in size, for example, some times 8 bytes, 40 bytes, or 191 bytes. The byte array (record is 99 bytes)
with no indicator of an end point and the start is always LOO or (0x4c4f4f). Also, the very first response from the serial port is an ACK (0x06) that I need to drop.

Here is an example of the data output:


The code I started with is:


In reality, I want to append only 99 bytes to byteResult[] and forward that on to a record processor to parse the data.
I know I need to just process this at the byte level but have not been able to figure out an approach.

I am looking for guidance in approach (yes, an example would be great but guidance so I can push myself on coding it would be great as well.)
I know if I can get this figured out the solution can be used in other places as well.

Thanks
Mike
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 3035
    
    4

You might want to look into using a ByteBuffer to collect data into. For example read from the source in chunks and copy the data to the ByteBuffer. Then, if the ByteBuffer is >99 bytes long:
-- consume the first 99 bytes
-- remove any of the unwanted bytes
-- replace any removed bytes with remaining bytes from the buffer
-- -- may need to re-read more bytes if not enough left in the buffer for the replacement
-- compact the buffer so leftover bytes are the beginning of the next record
-- send the 99 bytes back as a record

If you read up on ByteChannels and the NIO packages, then you might be able to more directly link your ByteBuffer to the source.


Steve
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 32675
    
    4
Too difficult for "beginning". Moving thread.
Mike Bates
Ranch Hand

Joined: Sep 19, 2009
Posts: 81
Okay,

I took the idea and started coding (mix of pseudo code and code), it has not been tested yet.

Am I on the right track?


Riche, I did not realize this was to complex for beginning java and will assess before posting again there.

Thanks
Mike

Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 3035
    
    4

I don't think am following what you are doing. But I am pretty sure it isn't correct. First let's start with the loop where you are reading from the InputStream:


It is possible to continue to read through the entire stream this way, and then when the loop is completed numBytes would be -1. What happens if you first read 500 bytes from the Stream in one chunck, and then read 10 bytes from the stream, after which there are no more available bytes? Then the numBytes is set to 10, you lost the first 10 bytes read from the Stream and you have to reconstruct the rest by reading bytes 11->490 first, then reading 1->10. The best way to read from an input stream is like this:

This way, you will read in up to 1024 byte chunks. The actual amount read in each chunk is recorded in the numBytes variable. Inside the loop you can work with 0-numBytes to process every byte read. The loop knows to stop when numBytes = -1, which signals end of stream. So in your code, it might look something like this:


Now, I can't follow what you were trying to do in the rest of the code you posted. Here is what I would do though (and why I would go with ByteBuffer)

1) You have a number of bytes you read, which could be any amount from 0 to 1024. You could have read a small part of a 'report' of 99 bytes you need, or you may have read up to 10 'reports' with some extra bytes. So make sure you keep track of all the extra bytes that can come between chunks, dump everything into the ByteBuffer. This would mean that the ByteBuffer should be larger than your readBuffer just to make sure that no overflow occurs from a partial read immediately followed by a complete read:

2) The ByteBuffer has a bulk get() method that will fill an array. When building the report-sized array I would use this method. Something like:


3) Then it is just a matter of getting from the 'filling' stage in 1) to the 'reporting' stage in 2). This is just a matter of preparing the ByteBuffer for reading, rather than writing, then reading as many 'reports' as are present in the buffer, then making the buffer ready again for writing. Methods that will help you:
flip() - prepare for reading
remaining() - Check number of remaining bytes (if remaining() >= 99 then make report, for example)
compact() - prepare for writing

That last step is just a bit of glue, and you would probably end up calling the 'getRportArray()' method in a loop to handle cases when one read chunk reads > 99 bytes of data.

Any kind of byte checking to remove un-wanted bytes would be done on top of this (for example you can consume the InputStream up to the point where the ACK signal is reached BEFORE calling the stream reading code I provided up top).
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 3035
    
    4

p.s. I edited your first post so we don't have to scroll sideways a lot to view the post.
 
I agree. Here's the link: http://ej-technologies/jprofiler - if it wasn't for jprofiler, we would need to run our stuff on 16 servers instead of 3.
 
subject: Reading variable size buffer into an byte array
 
Similar Threads
URGENT - converting bytes to Strings
Pooling Serial port
Converting data file to text file
POSTing from applet to servlet
how to create an image through bufferedimage,image and other helper class using byte array