1

I have a very small threaded application, which is collecting small chunks of data in arrays (because it is sound data, and Java wants that to be an array) and trying to put it into an ArrayList for storage. All of that is effectively the front half of a producer/consumer pattern.

Problem: It doesn't seem to work.

On the producer end, I have this code:

  public synchronized void run() {
// do a whole bunch of audio set-up

try {
  // more audio stuff

  while (true) {
    if (producing) {
      byte[] data = new byte[line.getBufferSize() ];
      numBytesRead = line.read(data, 0, data.length);
      System.out.println("Producer:  Size of dat[] is " + data.length);

      // Save this chunk of data.
      buffer.addData(data);
    }

This seems straightforward, aside from the audio stuff and bookkeeping.
In the buffer class, I have:

public class Buffer {
  ArrayList list ;
  public void addData(byte[] data) {
    list.addAll(Arrays.asList(data));
  }

This also seems straightforward. Here is the problem: If my array is of length (say) 1024, and the elements are all there (which I've verified that they are) I would expect the size of the ArrayList to grow by 1024 every time I add data. It doesn't. It grows by 1, as though I was making either an ArrayList of ArrayLists or an ArrayList of Arrays, rather than the Arraylist of elements I desire.

I suspect I'm going to have this problem on the flip side as well, where I might have an ArrayList of tens of thousands of bytes, and want to retrieve an array of the first 1024 elements.

I cannot help but think I'm missing something very simple. Can anyone shed light on why this is not working? (Or if there is some fundamentally better way to do what I'm trying to do?)

5
  • You should also synchronize the method addData() if it is accessed from more then one thread per instance of Buffer Commented Mar 17, 2012 at 21:54
  • @amit you're correct, of course. I've added it since you reminded me, but I hadn't written any other method touching it since adding the data wasn't working correctly anyway. Commented Mar 17, 2012 at 22:00
  • Add some typing to your List and the error will reveal by itself. I believe your mistake lies in your call to Arrays.asList() which does not return a List<Byte> but a List<Byte[]> Commented Mar 17, 2012 at 22:01
  • 1
    Take a look at stackoverflow.com/questions/754294/… Commented Mar 17, 2012 at 22:04
  • @AKJ, yes, I think that's what I'm looking for. It works; we'll see if the memory bloat kills the concept. Commented Mar 17, 2012 at 22:23

3 Answers 3

4

Arrays.asList() will not perform the conversion from byte to Byte, it will return a list containing 1 element; the byte[] you pass in.

If your aim is to add Byte objects for every byte, you will have to do that yourself in a loop. Note that this will use much more memory than passing byte[]s however.

Also note that it is not garuanteed that, even if the input stream has more than enough data left, that you will read data.length bytes every time (result of buffer sizes, concurency, etc.) so you run the risk of passing a bunch of 0 bytes at the end of your buffer if you read less bytes than you asked for.

Sign up to request clarification or add additional context in comments.

Comments

1

byte[] data should be Byte[]. You must use object, not primitive.

Comments

0

I cannot help but think I'm missing something very simple. Can anyone shed light on why this is not working? (Or if there is some fundamentally better way to do what I'm trying to do?)

Storing byte data in an ArrayList<Byte> has a lot of memory overhead, compared to a byte[] array. if you're working with a large amount of data, you may want to use a byte[] array for storage as well. Take a look at the source code for ByteArrayOutputStream - I don't know if will work for you as-is, but you might be able to create a similar sort of class that manages an expanding byte array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.