By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,032 Members | 811 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,032 IT Pros & Developers. It's quick & easy.

datainput stream

P: n/a
hi all

i was trying to read an integer from keyboard with DataInputStream
can someone explain the behaviour of the following code ????

<code>
DataInputStream dis=new DataInputStream(System.in);
DataOutputStream dout = new DataOutputStream(System.out);
a=dis.readInt();
System.out.println("Using system.out a = "+a);
dout.writeInt(a);
a++;
System.out.println("Using system.out a = "+a);
dout.writeInt(a);
dout.flush();
</code>

the output is as under when 56 was entered as input
<output>
Using system.out a = 892734730
56
Using system.out a = 892734731
56

</output>

isnt it logical that if readInt reads an integer (56) , variable a
should store 56 & not some other value ....
what format does the DataInput reads in ?
coz when DataOutput is used the 56 appears corectly also the character
' ' where did it come from :O ?

how do you store value in an int variable using DataInputStream or is
it not meant for that ;) ?
i understand that stream stores it in different format that System.out
does not understand
but if we use the variable 'a' in some computation (of course we will
otherwise why will you want to read it ;) )then the whole computation
will go wrong
what am i missing ?

amey
Jul 17 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
"Amey Samant" <am*****@yahoo.com> wrote in message
news:66**************************@posting.google.c om...
hi all

I was trying to read an integer from keyboard with
DataInputStream can someone explain the behaviour
of the following code ????

<code>
DataInputStream dis=new DataInputStream(System.in);
DataOutputStream dout = new DataOutputStream(System.out);
a=dis.readInt();
System.out.println("Using system.out a = "+a);
dout.writeInt(a);
a++;
System.out.println("Using system.out a = "+a);
dout.writeInt(a);
dout.flush();
</code>

the output is as under when 56 was entered as input
<output>
Using system.out a = 892734730
56
Using system.out a = 892734731
56

</output>

isnt it logical that if readInt reads an integer (56) ,
variable a should store 56 & not some other value ....
what format does the DataInput reads in ?

It is designed to read in a value which is encoded as a binary integer. The
values from 'System.in' are *not* so-encoded, therefore you get what appear
to be random or nonsense values.

The data from 'System.in' is, instead, encoded as characters. When
performing interactive console I/O you will find that input is merely a
series of characters terminated by the newline character. Given this, the
usual method for performing such I/O is something like:

BufferedReader br =
new BufferedReader(
new InputStreamReader(System.in));

String input;

while ((input = br.readLine()) != null)
{
...
System.out.println("Input Line: " + input);
...
int i;

try
{
i = Integer.parseInt(input);
System.out.println("Converted integer value: " + i);
}
catch (NumberFormatException e)
{
// error ...
}
...
}

coz when DataOutput is used the 56 appears corectly also
the character ' ' where did it come from :O ?

how do you store value in an int variable using
DataInputStream or is it not meant for that ;) ?

It's actually meant to decode data that was originally written using a
'DataOutputStream' ! Although the results look strange, it is behaving
*exactly* as it should. The problem, as mentioned earlier, is that the wrong
type of data has been supplied to 'readInt'.

i understand that stream stores it in different format that
System.out does not understand but if we use the variable
'a' in some computation (of course we will otherwise why
will you want to read it ;) )then the whole computation
will go wrong what am i missing ?


It's a problem that traps many Java novices - live and learn :) !

I hope this helps.

Anthony Borla
Jul 17 '05 #2

P: n/a
hi
It is designed to read in a value which is encoded as a binary integer. The
values from 'System.in' are *not* so-encoded, therefore you get what appear
to be random or nonsense values.
The data from 'System.in' is, instead, encoded as characters. When
performing interactive console I/O you will find that input is merely a
series of characters terminated by the newline character.
i did not follow this, i mean System.in is an object of InputStream
which is ByteStream & not a character stream so what is your point ???
It's actually meant to decode data that was originally written using a
'DataOutputStream' ! Although the results look strange, it is behaving
*exactly* as it should. The problem, as mentioned earlier, is that the wrong
type of data has been supplied to 'readInt'.


http://java.sun.com/docs/books/tutor...ataIODemo.java

this is an example from SUN s tutorial on I/O
believe me when i downloaded this, compiled & run it DIDNT work
the input read with readInt() appears like "?????"
try it & let me know if you get the same thing
i use WinXP , j2se 1.4.1_02

amey
Jul 17 '05 #3

P: n/a

"Amey Samant" <am*****@yahoo.com> wrote in message
news:66**************************@posting.google.c om...
It is designed to read in a value which is encoded as a
binary integer. The values from 'System.in' are *not*
so-encoded, therefore you get what appear to be
random or nonsense values.
The data from 'System.in' is, instead, encoded as
characters. When performing interactive console
I/O you will find that input is merely a series of
characters terminated by the newline character.


i did not follow this, i mean System.in is an object of
InputStream which is ByteStream & not a character
stream so what is your point ???


My point, and the only reason for my bothering to respond to your query, was
to help you solve your problem, and, as a by-product, help teach you a
little about streams.

Try the code I posted - it illustrates a known, efficient, and reliable
method for interactively extracting 'int' values from a character input
stream.
It's actually meant to decode data that was originally
written using a 'DataOutputStream' ! Although the results
look strange, it is behaving *exactly* as it should. The
problem, as mentioned earlier, is that the wrong type of
data has been supplied to 'readInt'.


http://java.sun.com/docs/books/tutor...dot1/DataIODem
o.java
this is an example from SUN s tutorial on I/O
believe me when i downloaded this, compiled & run it DIDNT
work the input read with readInt() appears like "?????"
try it & let me know if you get the same thing
i use WinXP , j2se 1.4.1_02


No, I don't have the time to conduct such experiments. I believe I've been
more than helpful:

* Posted useful code which you can modify and use
* Briefly described why you were experiencing such
difficulties

I suggest that you re-read the tutorials noting the reasons why both stream
and reader [character stream] classes exist.

Anthony Borla
Jul 17 '05 #4

P: n/a
"Anthony Borla" <aj*****@bigpond.com> wrote in message news:<90***************@news-server.bigpond.net.au>...
"Amey Samant" <am*****@yahoo.com> wrote in message
news:66**************************@posting.google.c om... No, I don't have the time to conduct such experiments. I believe I've been
more than helpful:

* Posted useful code which you can modify and use
* Briefly described why you were experiencing such
difficulties

I suggest that you re-read the tutorials noting the reasons why both stream
and reader [character stream] classes exist.
Anthony Borla


hi
first of all thanx for taking your precious time out to help me
i dont know what level you cosider yourself at with java but i request
you think this from a "novice" point of view

THIS IS WITH REFERENCE TO DOCUMENTATION FOR j2se

1. System.in is an InputStream
2. DataInputStream has a constructor that takes InputStream
so new DataInputStream(System.in) is absolutely right
3. now DataInputStream has a method with following signature
public final int readInt()throws IOException
4. thus if i write
int a=(new DataInputStream(System.in)).readInt();
it should store an integer in variable 'a' as the return type is an
'int' for readInt()
5. now when you print this 'a' using System.out.println(a);
why should it not print correctly ??????

the method you suggested is "long cut" however well known it might be
i mean to read an integer why i have to read a Line & parse the int

there must be other easier way
also im not looking for a method to read an integer ....you can read
it thousand ways ....
i was freaked by above points
i hope i make it clear

can anyone explain not just "Anthony Borla"

amey
Jul 17 '05 #5

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Amey Samant wrote:

[snip]
hi
first of all thanx for taking your precious time out to help me
i dont know what level you cosider yourself at with java but i
request you think this from a "novice" point of view

THIS IS WITH REFERENCE TO DOCUMENTATION FOR j2se

1. System.in is an InputStream
2. DataInputStream has a constructor that takes InputStream
so new DataInputStream(System.in) is absolutely right
3. now DataInputStream has a method with following signature
public final int readInt()throws IOException
4. thus if i write
int a=(new DataInputStream(System.in)).readInt();
it should store an integer in variable 'a' as the return type is
an
'int' for readInt()
5. now when you print this 'a' using System.out.println(a);
why should it not print correctly ??????

the method you suggested is "long cut" however well known it might
be i mean to read an integer why i have to read a Line & parse the
int

there must be other easier way
also im not looking for a method to read an integer ....you can read
it thousand ways ....
i was freaked by above points
i hope i make it clear

can anyone explain not just "Anthony Borla"

amey


Hi,
OK, here's another explanation.

First, there is a difference between bytes and characters. In Java, a
character is Unicode, 2 bytes long. A byte is 1 byte long
(obviously). A character is a piece of a human language, while a byte
is a piece of a computer data storage mechanism. In Java, a <char>
data type is a way of representing a human character in terms of
computer storage. *IN GENERAL*, streams transfer bytes and readers
transfer characters.

Alright, here we go. This is what happens in your code.

1. The user types in 58 and presses ENTER. This consists of three
characters: '5', '8', '\r', and '\n'. The operating system sends
these characters to the Java VM's standard input stream as bytes.
These bytes would typically be along the lines of 53, 56, 13, and 10.
These are the ASCII codes for the said characters. It is these bytes
that are sent to the JVM.

2. The JVM sends these bytes directly to your program by means of
System.in. This _STREAM_ reads the bytes, one after the other.

3. The DataInputStream takes the bytes from System.in and tries to
generate an int value. An int value requires 4 bytes, and I'm not
sure in which order they're used. Essentially, though, the 53, 56,
13, and 10 are used to generate the int value that is returned by
readInt(). The DataInputStream doesn't know, nor does it CARE,
*WHERE* these bytes came from! All it knows is that it got them from
somewhere. It doesn't know nor care that they are characters the user
typed on the console. Thus, you definitely don't get the value you
were looking for!

As has already been pointed out, DataInputStream reads numbers
correctly if they are written with DataOutputStream. If you feed 58
to DataOutputStream's writeInt() method, you'll get bytes 0, 0, 0,
and 58. By examining the ASCII table, we see this computes to NUL,
NUL, NUL, and colon (:). If you were to feed these four bytes back
into DataInputStream, you would get the proper value of 58 out.

In short, DataInputStream is meant to be used only to read in data
written with DataOutputStream. They do not, and are not intended to,
output data in a human-readable format; rather, they use the most
compact and efficient way possible for a computer to represent the
values.

The fact is, you're reading characters from a stream that happens to
be connected to a keyboard. Therefore, the origins of the data are
*characters*: the keyboard has letters and numbers on it; these are
elements of a human language, so they're characters, not bytes. The
fact is, the operating system sends the characters to your program in
the form of bytes. Since they were originally characters, they should
be translated back into characters before use for any other purpose.
The correct way to transform bytes into characters is to use an
InputStreamReader. This makes sense in the stream/reader system: the
stream passed in produces bytes, and the reader (the
InputStreamReader) generates characters. Thus, the bytes are turned
into characters. Now, since you want the user to type one number and
press ENTER, this means there is one number per line.
InputStreamReader doesn't directly support reading in a line at a
time, so you could do it manually or, the easier way, you could wrap
it in a BufferedReader, which does have this functionality. Reading a
line gives you a String, which makes sense, since the user types a
string of characters before pressing ENTER. Your program wants a
number, so it calls parseInt() to acquire one.

The important thing to remember here is that there are certain
transformations that go on in the operating system, and other
transformations that your program must perform to correctly work with
the data. These are the operations performed to read an integer from
the keyboard, in a typical operating system:

1. User presses keys. Microcontroller in keyboard produces scancodes,
which are numbers identifying the keys, which are sent to the
computer.

2. The operating system reads these scancodes and uses a keyboard map
to figure out what keys they represent. The OS then somehow
transforms the sum total of keys pressed (shift, control, etc plus a
letter) into a character (uppercase, lowercase, etc).

3. The character is translated into one or more bytes by the OS.

4. The OS sends these bytes to the program (the JVM).

5. The JVM sends the characters to your program by way of the
System.in stream.

6. Your program transforms the bytes into characters by way of the
InputStreamReader.

7. Your program reads a bunch of characters, representing a line, into
a String representing that bunch of characters.

8. Your program transforms the bunch of characters, in the String,
into a number, by way of parseInt().

So you see, characters come into the JVM in the form of bytes.
Changing this would require modifying the operating system and every
program running on it, including the JVM.

I hope this helped you understand, and I hope it didn't seem too
"dumbed-down" - but better too dumbed-down than too high-level.

- --
Chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)

iD8DBQE/16+KwxczzJRavJYRAqsuAJ9FKA3nzoXEEKbK6bOj7GTzYRu1SA CeKkEf
HhaylkRBiheU6p/j1f0+OGo=
=pJD9
-----END PGP SIGNATURE-----
Jul 17 '05 #6

P: n/a
hi all
got all the mess sorted out finally
the readInt method though returns "int" is meant to read data written
by writeInt
it reads 4 bytes so if you enter 45
the int will be stored as ascii values of foloowing chars serailly
starting high order byte first
4
5
\n
\r

i also got the reason why their demo code failed
on windows platform when the input is entered it also reads \n & \r
whereas on *nix platform it reads only \n & not \r so i modified their
code to writeChar('\r) also & then it works fine
i should have read the DOCS with utmost care ;)
i was confused as i saw the return type as 'int'

cheers
amey
Jul 17 '05 #7

P: n/a

"Amey Samant" <am*****@yahoo.com> wrote in message
news:66**************************@posting.google.c om...
"Anthony Borla" <aj*****@bigpond.com> wrote in message news:<90***************@news-server.bigpond.net.au>...
"Amey Samant" <am*****@yahoo.com> wrote in message
news:66**************************@posting.google.c om...


<SNIP>
hi
first of all thanx for taking your precious time out to
help me

Thank you for this little bit of courtesy. None of us here is paid to
provide help, so its reassuring to know that the genuine, in-good-faith
effort made in providing it is appreciated even if it doesn't solve the
originally posted problem.

i dont know what level you cosider yourself at with java
but i request you think this from a "novice" point of view

My reading of your original post led me to believe that it was a novice
level query. There was, also, nothing specifically stated in your original
post to indicate otherwise. In the absence of specific information a reader
has to infer, making assumptions based on that.

More specifically, I sensed that you did not understand the difference
between the different types of streams [i.e. byte streams and character
streams], and I responded with this belief in mind. In particular, I:

* Provided working code which performed the task you
appeared to want to accomplish

* Pointed you to the Sun tutorials, a very useful information
source

I'm satisfied I provided a decent quality of help in this instance.
<SNIP>
can anyone explain not just "Anthony Borla"


It looks like you got your wish :) !

Cheers,

Anthony Borla
Jul 17 '05 #8

P: n/a

"Chris" <ch*******@hotmail.com> wrote in message
news:WQQBb.53431$bC.22421@clgrps13...
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

OK, here's another explanation.

<SNIP>

Superb explanation, Chris, just superb :) !

Cheers,

Anthony Borla
Jul 17 '05 #9

P: n/a
hi chris

your explanation certainly made my basic concepts solid
though i could actually figure out what went wrong with the help of
one of my friend, your explanation deserves appreciation :)
as i also mentioned previous post that i got confused by the return
type of readInt ....
i should have read the docs carefully :) but then i would have missed
this entire conversation :D
i will also keep in mind about the '\n' and '\r' on win while only
'\n' on nix

so if you have to write "real platform independent" code which uses
DataInputStream you must first get platform type and then write if
else to deal with \n \r thing :D
what you say
sounds like #if #elif code in c :D

cheers
amey

OK, here's another explanation. - -- Chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)

iD8DBQE/16+KwxczzJRavJYRAqsuAJ9FKA3nzoXEEKbK6bOj7GTzYRu1SA CeKkEf
HhaylkRBiheU6p/j1f0+OGo=
=pJD9
-----END PGP SIGNATURE-----

Jul 17 '05 #10

P: n/a
Amey Samant wrote:
i will also keep in mind about the '\n' and '\r' on win while only
'\n' on nix


it's interesting how windows terminates each line with
the \r\n sequence rather than unix's simpler \n.

the origin of the \r\n sequence dates way back to the
old FORTRAN days and teletype machines and lineprinters
that had lots & lots of mechanical parts. FORTRAN used
to close a line with CR LF but quickly they changed it
to CR CR LF because the machinery would get dirty & stick
& not complete a carriage return. the simple fix then
was to send a duplicated \r or CR, because this wouldnt
change the appearance & got rid the mechanical problem
in all but a few acceptably rare cases. later, when
the CR LF combo was combined into the newline character,
\n, the world split into 2 camps. the unix dudes, who
noted that the old mechanical problems of the past were
no longer a factor, opted to save a char by dropping the
\r. the windows dude kept loyal to the dinosaurian
method and came up with the CR \n sequence.

in the old days of teletype communications there were
guys stationed around the world to would send messages
to each other (infact there still are!). sometimes,
bored with sitting at the terminal on the graveyard
shift, guys might send a messages to each other's
typewriters along these lines:

1st guy: "HEY JOE - HOW ARE YOU?"
2nd guy: "HI BOB - PRETTY GOOD. NOTHING
GOING ON HERE"
1st guy: "I SNUCK IN MY HONEY TONIGHT.
GUESS WHAT WE'RE DOING RIGHT NOW!"
2nd guy: "WHAT?"
1st guy" "<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>
<SHIFTLOCK><F><SHIFTOFF><f>"
- nate
Jul 17 '05 #11

P: n/a
Amey Samant wrote:
hi chris

your explanation certainly made my basic concepts solid
though i could actually figure out what went wrong with the help of
one of my friend, your explanation deserves appreciation :)
as i also mentioned previous post that i got confused by the return
type of readInt ....
i should have read the docs carefully :) but then i would have missed
this entire conversation :D
i will also keep in mind about the '\n' and '\r' on win while only
'\n' on nix

so if you have to write "real platform independent" code which uses
DataInputStream you must first get platform type and then write if
else to deal with \n \r thing :D
what you say
sounds like #if #elif code in c :D


Java provides tools to help you deal with this in a sane fashion. For
example, BufferedReader will read a line and handle the '\n' or '\r\n'
issue for you. (Although I understand that it has problems on Mac
platforms, where the line separator is '\r'.)

For writing data, use the PrintStream or PrintWriter (actually, use
PrintWriter if at all possible), which have println() methods that will
append the proper line terminator.

Finally, if you need to know the line separator on the platform for any
reason, use System.getProperty("line.separator").

Please, please, please do not use any #if or #elif like expressions.
They give Java coders headaches. :)
Seriously, with the above tools I mentioned, you should be able to write
line handling code that looks elegant, is easy to maintain and is usable
on any platform.

Ray

Jul 17 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.