• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 371
  • Last Modified:

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.
0
Knightley
Asked:
Knightley
  • 13
  • 10
  • 10
2 Solutions
 
objectsCommented:
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
0
 
objectsCommented:
An ObjectInputStream/ObjectOutputStream could also be used to pass the entire array as an object
0
 
aozarovCommented:
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.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
KnightleyAuthor Commented:
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
0
 
aozarovCommented:
>> 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();





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

0
 
objectsCommented:
your read should look like:

for (int i=0; i<128; i++)
{
  dataRGB[i] = ip.readInt();
}
0
 
objectsCommented:
The read is likely whats causing your current problem.
0
 
aozarovCommented:
Add to the above:
DataInputStream ip = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
0
 
aozarovCommented:
>> 1. seems i only could receive dataRGB[0], the other elements are sent but not received by my inputStream.
Looks like your first integer is happen to equal to -1

>> 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?

Maybe this limit is imposed by your J2ME device buffer (in that case flushing more frequent might actually be helpful).
0
 
objectsCommented:
> Looks like your first integer is happen to equal to -1

Yes I mentioned that earlier :)
0
 
aozarovCommented:
>> 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.
0
 
objectsCommented:
ROTFL
0
 
KnightleyAuthor Commented:
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?


0
 
objectsCommented:
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
0
 
objectsCommented:
op.writeInt(data_1.length);
for (int i = 0; i < data_1.length; i++) {
    op.writeInt(data_1[i]);
}

op.writeInt(data_2.length);
for (int i = 0; i < data_2.length; i++) {
    op.writeInt(data_2[i]);
}
op.flush();
0
 
objectsCommented:
You can then read the length on the recieving end and use that in the for loop to read the array
0
 
KnightleyAuthor Commented:
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?
0
 
objectsCommented:
> 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
0
 
KnightleyAuthor Commented:
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?
0
 
objectsCommented:
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();
}
0
 
KnightleyAuthor Commented:
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. :)
0
 
aozarovCommented:
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?
0
 
KnightleyAuthor Commented:
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.
0
 
KnightleyAuthor Commented:
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.
#
0
 
aozarovCommented:
>> 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.
0
 
aozarovCommented:
And if you don't need it to run in a seperate thread then put that logic instead of the thread.start() part.
0
 
aozarovCommented:
>> Not the other way around. J2ME does not incl. BufferedArray class.
Right, not for MIDP (though it does exist for CDC)
0
 
KnightleyAuthor Commented:
>>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. :)
0
 
KnightleyAuthor Commented:
thanx very much for the help.
0
 
aozarovCommented:
>> 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?)
       }
   }
}

0
 
objectsCommented:
no worries :)
0
 
KnightleyAuthor Commented:
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.

0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 13
  • 10
  • 10
Tackle projects and never again get stuck behind a technical roadblock.
Join Now