Link to home
Start Free TrialLog in
Avatar of Knightley
Knightley

asked on

Sending int[] Array using DataInputStream / DataOuputStream

This is the code i am using, but i think i am neither efficient nor right. :(

I have a RGB image:
int[] dataRGB;
dataRGB.length=128;
which i would like to send via DataOuputStream

for (int i = 0; i < 128; i++) {
    op.writeInt(data[i]);
    op.flush();
}

---------------------------------------------------------------------
To receive the stream:

public void run(){
        int i = 0;
        int[] dataRGB = new int[128];
        int received_data = 0;
        while ( (received_data = ip.readInt()) != -1) {
          dataRGB[i] = received_data;
          i++;
}
}

The problems:
1. seems i only could receive dataRGB[0], the other elements are sent but not received by my inputStream.
2. If i try to send a bigger Array, like length = 2000, it looks like there is some limit about how much data i could send
    per outputstream, could anyone confirm this?

Any help would be nice.

Thanx.
Avatar of Mick Barry
Mick Barry
Flag of Australia image

theres no limit.

>   while ( (received_data = ip.readInt()) != -1) {

readInt() does not return -1 on eof, it throws an exception.
If you know how many elements use a for loop, otherwise loop until exception thrown
An ObjectInputStream/ObjectOutputStream could also be used to pass the entire array as an object
Avatar of aozarov
aozarov

To optimize performance make your DataOuputStream/DataInputStream wrap BufferedOutputStream/BufferedInputStream.
e.g.
DataOuputStream op = new DataOutputStream(new BufferedOutputStream(your_output_stream_dst));
And don't flush after each integer you are writing to the stream.
Avatar of Knightley

ASKER

I am using the codes in J2ME, neither ObjectInputStream nor BufferedOutputStream seem
to be availble.

So how should change my code, like this:???

for (int i = 0; i < 128; i++) {
    op.writeInt(data[i]);
    if(i== 128){
    op.flush();
   }
}
what is the difference when i call flush every time or at the end??

I still do not know how read the input.

some example???

thanx
>> I am using the codes in J2ME, neither ObjectInputStream nor BufferedOutputStream seem to be availble.
Right (those are part of the RMI framework which is not avaiable in the J2ME SDK).

>> what is the difference when i call flush every time or at the end??
Just making it slower (what is the point).
Though I just noticed that you are flushing only at the end.

I assume op was constructed from some InputStream (such as socket).
so you can do:
DataOuputStream op = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
for (int i = 0; i < 128; i++)
    op.writeInt(data[i]);

op.flush();





the write codes fine, I'd just move the flush to the end of the loop.

your read should look like:

for (int i=0; i<128; i++)
{
  dataRGB[i] = ip.readInt();
}
The read is likely whats causing your current problem.
Add to the above:
DataInputStream ip = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
SOLUTION
Avatar of aozarov
aozarov

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> Looks like your first integer is happen to equal to -1

Yes I mentioned that earlier :)
>> Yes I mentioned that earlier :)
Sorry, I don't see that. I see "readInt() does not return -1 on eof, it throws an exception." which is something else.
ROTFL
Actually, My codes loks like this:

StreamConnection   OR_conn = (StreamConnection) Connector.open(OR_conn_string);
DataInputStream     OR_input = OR_conn.openDataInputStream();
DataOnputStream    OR_output = OR_conn.openDataOutputStream();

So the
DataInputStream ip = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
will probably not work... i guess.

Ahh, one last thing. What shoul i modify if my array's length is not known, and i send 2 arrays.
Do i have to open another connection? Or should i send a header to notify which array i am sending?


So here is what i am writing to outstream:

for (int i = 0; i < data_1.length; i++) {
    op.writeInt(data_1[i]);
}

for (int i = 0; i < data_2.length; i++) {
    op.writeInt(data_2[i]);
}
op.flush();

************************************
and to read the inputstream, how do i know
where the first array ends and where the 2. array start.

Do i need to send a int to notify that  the 1. array is finished?


Whether u buffer on not won't make a difference wrt you problem (it may well alreay be buffered anyway).

>  What shoul i modify if my array's length is not known, and i send 2 arrays.

You'll need to send the size of the array before sending the contents
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You can then read the length on the recieving end and use that in the for loop to read the array
so the "op.writeInt(data_1.length);"
will initiate my loop to read the array???

i also need a endless loop to wait for the "data_1.length",
should i use a while(true) loop to wait for the "data_1.length" input?
> i also need a endless loop to wait for the "data_1.length",

no loop required, the call to readInt() will block until data is available
you mena like this:

------------------------------
int length;
length = ip.readInt();

for (int i=0; i<length; i++)
{
  data[i] = ip.readInt();
}
-------------------------------

Does this work when i send the array AGAIN?
or do i have to create a new streamInput/Output?
you would duplicate that to read the other array

length = ip.readInt();

for (int i=0; i<length; i++)
{
  data2[i] = ip.readInt();
}

length = ip.readInt();

for (int i=0; i<length; i++)
{
  data2[i] = ip.readInt();
}
Say, i want to send the Array over and over again.
(like an updated array each time.)

should i put this in a run thread?

like:

public void run(){

length = ip.readInt();
for (int i=0; i<length; i++) {
  data2[i] = ip.readInt();
}

}

sorry, for so many further questions, it is just the anwsers are
not what i expected. :)
As I am not sure if your streams are buffered (there is nothing to suggested that they are) I would still suggest you to apply the bufferes (you can see yourself if this makes any difference, it should not hurt).
That can be done this way:

StreamConnection   OR_conn = (StreamConnection) Connector.open(OR_conn_string);
DataInputStream     OR_input = new DataInputStream(new BufferedInputStream(OR_conn.openInputStream()));
DataOutputStream    OR_output = new DataOutputStream(new BufferedOutputStream(OR_conn.openOutputStream()));

Also, if you are reading the size of the array dynamically you might want to the arrays based on given size.
e.g:

int length = ip.readInt();
int[] data1 = new int[length]; // initialize the data1 based on the given length (if data1 is a member variable the you can ommit the int[] part)
for (int i=0; i<length; i++)
  data1[i] = ip.readInt();


length = ip.readInt();
int[] data2 = new int[length]; // initialize the data2 based on the given length (if data2 is a member variable the you can ommit the int[] part)
for (int i=0; i<length; i++)
  data2[i] = ip.readInt();


>> should i put this in a run thread?
This logic will read and populate the two arrays. I don't know your application enough to tell if that is needed to be done in a seperate thread.
Any reason for it?
well, i intend to use only one thread like:

run(){

int arrayID = ip.readInt();
int length = ip.readInt();

switch (arrayID){
case 1:
for (int i=0; i<length; i++) {
  data1[i] = ip.readInt();}
  break;
case 2:
  for (int i=0; i<length; i++) {
  data2[i] = ip.readInt();}
  break;
default:break;
 }
}

and when the array is finished, it waits for a new array.
Is this correct?

Yes, i tried the bufferedStream, much fasterthan without.
Though i could only use it to send arrays to my phone.
Not the other way around. J2ME does not incl. BufferedArray class.
Funny when i use the BufferedStream, everything works fine, though a error message comes up when
i clos the app. Anything i have forgotten or i should just ignore it ?

Unexpected Signal : EXCEPTION_ACCESS_VIOLATION (0xc0000005) occurred at PC=0x8073F2A
Function=[Unknown.]
Library=D:\programming\j2sdk1.4.2_05\jre\bin\client\jvm.dll
NOTE: We are unable to locate the function name symbol for the error
      just occurred. Please refer to release documentation for possible
      reason and solutions.

Local Time = Tue May 03 19:43:01 2005
Elapsed Time = 84
#
# HotSpot Virtual Machine Error : EXCEPTION_ACCESS_VIOLATION
# Error ID : 4F530E43505002EF
# Please report this error at
# http://java.sun.com/cgi-bin/bugreport.cgi
#
# Java VM: Java HotSpot(TM) Client VM (1.4.2_05-b04 mixed mode)
#
# An error report file has been saved as hs_err_pid1292.log.
# Please refer to the file for further information.
#
>> Funny when i use the BufferedStream, everything works fine, though a error message comes up when
Strange, that normally should not happen when dealing with the Java API.
Does it happen once or everytime?
Try closing the streams before you close your application.


If you want to read the arrays one after the other then why do you need the case for?
Just put the logic one after the other exactly as I showed one comment above.
And if you don't need it to run in a seperate thread then put that logic instead of the thread.start() part.
>> Not the other way around. J2ME does not incl. BufferedArray class.
Right, not for MIDP (though it does exist for CDC)
>>And if you don't need it to run in a seperate thread then put that logic instead of the thread.start() part.

The 2 arrays are modified kind of randomly, and each time they are change, i want to send them to my phone.
so i need to send some thing first to let my phone which array is being sent.


about the error message, well they are gone when i clos the connection. :)
thanx very much for the help.
>> about the error message, well they are gone when i clos the connection. :)
:-)

>> The 2 arrays are modified kind of randomly, and each time they are change, i want to send them to my phone.
Ok, I think I see why you need the Thread now. you are going to keep reading forever, right?
If so, you can do something like that:

public void run()
{
     while (true)
     {
         try
        {
            int arrayID = ip.readInt();
            int length = ip.readInt();
            int[] array = new int[length];
            for (int i=0; i<length; i++)
               array[i] = ip.readInt();

            if (arrayID == 1)
                data1 = array;
            else
                data2 = array;
        }
        catch (IOException ex)
       {
          // Handle this exception (log?)
       }
   }
}

no worries :)
There is something about the the StreamOutput,
when i close my midlet on my mobile phone,
while the streamoutput from my pc is not finished,
the application windows crashes.