Java Reference
In-Depth Information
try
{
FileInputStream
in
=
new
FileInputStream
(
filename
);
MessageDigest
sha
=
MessageDigest
.
getInstance
(
"SHA-256"
);
DigestInputStream
din
=
new
DigestInputStream
(
in
,
sha
);
while
(
din
.
read
()
!=
-
1
)
;
din
.
close
();
byte
[]
digest
=
sha
.
digest
();
StringBuilder
result
=
new
StringBuilder
(
filename
);
result
.
append
(
": "
);
result
.
append
(
DatatypeConverter
.
printHexBinary
(
digest
));
System
.
out
.
println
(
result
);
}
catch
(
IOException
ex
)
{
System
.
err
.
println
(
ex
);
}
catch
(
NoSuchAlgorithmException
ex
)
{
System
.
err
.
println
(
ex
);
}
}
public
static
void
main
(
String
[]
args
)
{
for
(
String
filename
:
args
)
{
Thread
t
=
new
DigestThread
(
filename
);
t
.
start
();
}
}
}
The
main()
method reads filenames from the command line and starts a new
DigestTh
read
for each one. The work of the thread is actually performed in the
run()
method.
Here, a
DigestInputStream
reads the file. Then the resulting digest is printed on
System.out
in hexadecimal encoding. Notice that the entire output from this thread is
first built in a local
StringBuilder
variable
result
. This is then printed on the console
with one method invocation. The more obvious path of printing the pieces one at a time
using
System.out.print()
is not taken. There's a reason for that, which we'll discuss
soon.
Because the signature of the
run()
method is fixed, you can't pass arguments to it or
return values from it. Consequently, you need different ways to pass information into
the thread and get information out of it. The simplest way to pass information in is to
pass arguments to the constructor, which sets fields in the
Thread
subclass, as done here.
Getting information out of a thread back into the original calling thread is trickier
because of the asynchronous nature of threads.
Example 3-1
sidesteps that problem by
never passing any information back to the calling thread and simply printing the results
on
System.out
. Most of the time, however, you'll want to pass the information to other
parts of the program. You can store the result of the calculation in a field and provide
a getter method to return the value of that field. However, how do you know when the
calculation of that value is complete? What do you return if somebody calls the getter