Java I/O: Chapter 5. Network Streams
Java I/O
By Elliotte Rusty Harold
1st Edition March 1999
1-56592-485-1, Order Number: 4851
596 pages, $34.95
Chapter 5.
Network Streams
In this chapter:
URLs
From its first days, Java has had the network in mind, more so than any other common programming language. Java is the first programming language to provide as much support for network I/O as it does for file I/O, perhaps even more--Java's
URL
,URLConnection
,Socket
, andServerSocket
classes are all fertile sources of streams. The exact type of the stream used by a network connection is typically hidden inside the undocumentedsun
classes. Thus, network I/O relies primarily on the basicInputStream
andOutputStream
methods, which you can wrap with any higher-level stream that suits your needs: buffering, cryptography, compression, or whatever your application requires.URLs
The
java.net.URL
class represents a Uniform Resource Locator like http://metalab.unc.edu/javafaq/. Each URL unambiguously identifies the location of a resource on the Internet. TheURL
class has four constructors. All are declared to throwMalformedURLException
, a subclass ofIOException
.public URL(String u) throws MalformedURLException
public URL(String protocol, String host, String file)
throws MalformedURLException
public URL(String protocol, String host, int port, String file)
throws MalformedURLException
public URL(URL context, String u) throws MalformedURLException
A
MalformedURLException
is thrown if the constructor's arguments do not specify a valid URL. Often this means a particular Java implementation does not have the right protocol handler installed. Thus, given a complete absolute URL like http://www.poly.edu/schedule/fall97/bgrad.html#cs, you construct aURL
object like this:URL u = null;
try {
u = new URL("http://www.poly.edu/schedule/fall97/bgrad.html#cs");
}
catch (MalformedURLException e) { }
You can also construct the
URL
object by passing its pieces to the constructor:URL u = null;
try {
u = new URL("http", "www.poly.edu", "/schedule/fall97/bgrad.html#cs");
}
catch (MalformedURLException e) { }
You don't normally need to specify a port for a URL; most protocols have default ports. For instance, the HTTP port is 80. Sometimes the port used does change, and in that case you can use the third constructor:
URL u = null;
try {
u = new URL("http", "www.poly.edu", 80, "/schedule/fall97/bgrad.html#cs");
}
catch (MalformedURLException e) { }
Finally, many HTML files contain relative URLs. The fourth constructor in the previous code creates URLs relative to a given URL and is particularly useful when parsing HTML. For example, the following code creates a URL pointing to the file 08.html, taking the rest of the URL from
u1
:URL u1, u2;
try {
u1 = new URL("http://metalab.unc.edu/javafaq/course/week12/07.html");
u2 = new URL(u1, "08.html");
}
catch (MalformedURLException e) { }
Once a
URL
object has been constructed, there are two ways to retrieve its data. TheopenStream()
method returns a raw stream of bytes from the source. ThegetContent()
method returns a Java object that represents the data. When you callgetContent()
, Java looks for a content handler that matches the MIME type of the data. It is theopenStream()
method that is of concern in this book.The
openStream()
method makes a socket connection to the server and port specified in the URL. It returns an input stream from which you can read the data at that URL, allowing you to download data from the server. Any headers that come before the actual data or file requested are stripped off before the stream is opened. You get only raw data.public final InputStream openStream() throws IOException
You read from the input stream using an input stream or reader class. For example:
try {
URL u = new URL("http://www.amnesty.org/");
InputStream in = u.openStream();
int b;
while ((b = in.read()) != -1) {
System.out.write(b);
}
}
catch (MalformedURLException e) {System.err.println(e);}
catch (IOException e) {System.err.println(e);}
Applets running under the control of a security manager--that is untrusted applets that run inside a web browser--are normally only allowed to connect back to the host they were downloaded from. This host can be determined from the URL returned by the
getCodeBase()
method of theApplet
class. Attempts to connect to other hosts throw security exceptions. You can create URLs that point to other hosts, but you may not download data from them usingopenStream()
or any other method. (This security restriction for applets applies to any network connection, regardless of how you get it.)Example 5-1 reads a series of URLs from the command line. The program connects to the specified URLs, downloads the data, and copies it to
System.out
.Example 5-1:
The URLTyper Programimport java.net.*;
import java.io.*;
import com.macfaq.io.*;
public class URLTyper {
public static void main(String[] args) {
if (args.length == 0) {
System.err.println("Usage: java URLTyper url1 url2 ...");
return;
}
for (int i = 0; i < args.length; i++) {
if (args.length > 1) {
System.out.println(args[i] + ":");
}
try {
URL u = new URL(args[i]);
InputStream in = u.openStream();
StreamCopier.copy(in, System.out);
in.close();
}
catch (MalformedURLException e) {System.err.println(e);}
catch (IOException e) {System.err.println(e);}
}
}
}
For example, here are the first few lines you see when you connect to http://www.oreilly.com/:
D:\JAVA\ioexamples\05>java URLTyper http://www.oreilly.com/
<HTML>
<HEAD>
<META name="keywords" content="computer books, technical books, UNIX, unix,
Perl, Java, Linux, Internet, Web, C, C++, Windows, Windows NT, Security,
Sys Admin, System Administration, Oracle, design, graphics, online books,
online courses, Perl Conference, Web-based training, Software, open source,
free software">
<META name="description" content="O'Reilly is a leader in technical and
computer book documentation for UNIX, Perl, Java, Linux, Internet,
Web, C, C++, Windows, Windows NT, Security, Sys Admin, System
Administration, Oracle, Design & Graphics, Online Books, Online Courses,
Perl Conference, Web-based training, and Software">
<TITLE>www.oreilly.com -- Welcome to O'Reilly & Associates!</TITLE>
Most network connections, even on LANs, are slower and less reliable sources of data than files. Connections across the Internet are even slower and less reliable, and connections through a modem are slower and less reliable still. One way to enhance performance under these conditions is to buffer the data: to read as much data as you can into a temporary storage array inside the class, then parcel it out as needed. In the next chapter, you'll learn about the
BufferedInputStream
class that does exactly this.URL Connections
URL connections are closely related to URLs, as their name implies. Indeed, you get a reference to a
URLConnection
by using theopenConnection()
method of aURL
object; in many ways, theURL
class is only a wrapper around theURLConnection
class. However, URL connections provide more control over the communication between the client and the server. In particular, URL connections provide not just input streams by which the client can read data from the server, but also output streams to send data from the client to the server. This is essential for protocols like mailto.The
java.net.URLConnection
class is an abstract class that handles communication with different kinds of servers, like FTP servers and web servers. Protocol-specific subclasses ofURLConnection
, hidden inside thesun
classes, handle different kinds of servers.Reading Data from URL Connections
URL connections take place in five steps:
- The
URL
object is constructed.- The
openConnection()
method of theURL
object creates theURLConnection
object.- The parameters for the connection and the request properties that the client sends to the server are set up.
- The
connect()
method makes the connection to the server, perhaps using a socket for a network connection or a file input stream for a local connection. The response header information is read from the server.- Data is read from the connection by using the input stream returned by
getInputStream()
or through a content handler withgetContent()
. Data can be sent to the server using the output stream provided bygetOutputStream()
.This scheme is very much based on the HTTP/1.0 protocol. It does not fit other schemes that have a more interactive "request, response, request, response, request, response" pattern instead of HTTP/1.0's "single request, single response, close connection" pattern. In particular, FTP and even HTTP/1.1 aren't well suited to this pattern. I wouldn't be surprised to see this replaced with something more general in a future version of Java.
URLConnection
objects are not constructed directly in your own programs. Instead, you create aURL
for the particular resource, and call thatURL
'sopenConnection()
method. This gives you aURLConnection
. Then thegetInputStream()
method returns an input stream that reads data from the URL. (TheopenStream()
method of theURL
class is just a thin veneer over thegetInputStream()
method of theURLConnection
class.) For example:try {
URL u = new URL("http://www.digitalthink.com/");
URLConnection uc = u.openConnection();
uc.connect();
InputStream in = uc.getInputStream();
//...
}
catch (IOException e) { //...
If the connection cannot be opened (possibly because the remote host is unreachable), an
IOException
is thrown. Example 5-2 reads a URL from the command line, opens a connection to that URL, then prints the data returned by the server at that URL. This is similar to Example 5-1;WebCat
differs primarily in that it uses aURLConnection
instead of aURL
.Example 5-2:
The WebCat Programimport java.net.*;
import java.io.*;
import com.macfaq.io.*;
public class WebCat {
public static void main(String[] args) {
if (args.length == 0) {
System.err.println("Usage: java WebCat url1 url2 ...");
return;
}
for (int i = 0; i < args.length; i++) {
if (i > 0 && i < args.length) {
System.out.println();
System.out.println("----------------------");
System.out.println();
}
System.out.println(args[i] + ":");
try {
URL u = new URL(args[i]);
URLConnection uc = u.openConnection();
uc.connect();
InputStream in = uc.getInputStream();
StreamCopier.copy(in, System.out);
in.close();
}
catch (IOException e) {System.err.println(e);}
} // end for
}
}
Writing Data on URL Connections
Writing data to a
URLConnection
is similar to reading data. However, you must first inform theURLConnection
that you plan to use it for output, and then, instead of getting the connection's input stream and reading from it, you get the connection's output stream and write to it. This is commonly used to talk to CGIs that use the POST method or to store files on web servers through the PUT method, or to communicate with a Java servlet running on a server. Here are the steps for writing data on aURLConnection
:
- Construct the
URL
object.- Call the
openConnection()
method of theURL
object to create theURLConnection
object.- Pass
true
tosetDoOutput(
) to indicate that thisURLConnection
will be used for output.- If you also want to read input from the stream, invoke
setDoInput(true)
to indicate that thisURLConnection
will be used for input.- Create the data you want to send, preferably as a byte array.
- Call
getOutputStream()
to get an output stream object. Write the byte array calculated in step 5 onto the stream.- Close the output stream.
- Call
getInputStream()
to get an input stream object. Read and write it as usual.Example 5-3 uses these steps to implement a simple mail client. It forms a mailto URL from an email address entered on the command line. Input for the message is copied from
System.in
onto the output stream of theURLConnection
using aStreamCopier
. The end of the message is indicated by the end-of-stream character.Example 5-3:
The MailClient Classimport java.net.*;
import java.io.*;
import com.macfaq.io.*;
public class MailClient {
public static void main(String[] args) {
if (args.length == 0) {
System.err.println("Usage: java MailClient username@host.com");
return;
}
try {
URL u = new URL("mailto:" + args[0]);
URLConnection uc = u.openConnection();
uc.setDoOutput(true);
uc.connect();
OutputStream out = uc.getOutputStream();
StreamCopier.copy(System.in, out);
out.close();
}
catch (IOException e) {System.err.println(e);}
}
}
For example, to send email to the author of this book:
% java MailClient elharo@metalab.unc.edu
hi there!
^D
MailClient
suffers from a few restrictions. The proper way to detect the end of the message is to look for a period on a line by itself. Proper or not, that style of user interface is really antiquated, so I didn't bother to implement it. To do so properly, you'll need to use aReader
or aWriter
; they're discussed in Chapter 15, Readers and Writers. Furthermore, it only works in Java environments that support the mailto protocol; thus, it works under Sun's JDK, but may not work in other environments. It also requires that the local host be running an SMTP server, or that the system propertymailhost
must contain the name of an accessible SMTP server, or that a machine in the local domain named mailhost be running an SMTP server. Finally, the security manager must permit network connections to that server, although this is not normally a problem in an application.Sockets
Before data is sent across the Internet from one host to another, it is split into packets of varying but finite size called datagrams. Datagrams range in size from a few dozen bytes to about 60,000 bytes. Anything larger, and often things smaller, must be split into smaller pieces before it can be transmitted. The advantage of this scheme is that if one packet is lost, it can be retransmitted without requiring redelivery of all other packets. Furthermore, if packets arrive out of order, they can be reordered at the receiving end of the connection.
Fortunately, packets are invisible to the Java programmer. The host's native networking software splits data into packets on the sending end and reassembles packets on the receiving end. Instead, the Java programmer is presented with a higher-level abstraction called a socket. The socket represents a reliable connection for the transmission of data between two hosts. It isolates you from the details of packet encodings, lost and retransmitted packets, and packets that arrive out of order. A socket performs four fundamental operations:
- Connect to a remote machine
- Send data
- Receive data
- Close the connection
A socket may not be connected to more than one host at a time. However, a socket may both send data to and receive data from the host to which it's connected.
The
java.net.Socket
class is Java's interface to a network socket and allows you to perform all four fundamental socket operations. It provides raw, uninterpreted communication between two hosts. You can connect to remote machines; you can send data; you can receive data; you can close the connection. No part of the protocol is abstracted out, as it is withURL
andURLConnection
. The programmer is completely responsible for the interaction between the network client and the server. To create a connection, you call one of theSocket
constructors, specifying the host you want to connect to. EachSocket
object is associated with exactly one remote host. To connect to a different host, you must create a newSocket
object:public Socket(String host, int port) throws UnknownHostException, IOException
public Socket(InetAddress address, int port) throws IOException
public Socket(String host, int port, InetAddress localAddr, int localPort)
throws IOException
public Socket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException
The
host
is a string like "www.oreilly.com
" or "metalab.unc.edu
", which specifies the particular host to connect to. It may even be a numeric, dotted quad string like "199.1.32.90
". This argument may also be passed as ajava.net.InetAddress
object.The
port
argument is the port on the remote host to connect to. A computer's network interface is logically subdivided into 65,536 different ports. As data traverses the Internet in packets, each packet carries not only the address of the host but also the port on that host at which it's aimed. The host is responsible for reading the port number from each packet it receives to decide which program should receive that chunk of data. Many services run on well-known ports. This means that the protocol specifies that the service should or must use a particular port--for example, HTTP servers generally listen on port 80.The optional
localAddress
andlocalPort
arguments specify which address and port on the local host the socket is to connect from, assuming more than one is available. Most hosts have many available ports but only one address. These two arguments are optional. If they're left out, the constructor will choose reasonable values.Sending and receiving data across a socket is accomplished with output and input streams. These are the methods to get both streams for the socket:
public InputStream getInputStream() throws IOException
public OutputStream getOutputStream() throws IOException
There's also a method to close a socket:
public synchronized void close() throws IOException
This effectively closes the socket's input and output streams as well. Any attempt to read from or write to them after the socket is closed will throw an
IOException
.Example 5-4 is yet another program that connects to a web server and downloads a specified URL. However, since this one uses raw sockets, it needs to both send the HTTP request and read the headers in the response. These are not parsed away as they are by the
URL
andURLConnection
classes; you use an output stream to send the request explicitly and an input stream to read the data back, including HTTP headers. Only HTTP URLs are supported.Example 5-4:
The SocketTyper Programimport java.net.*;
import java.io.*;
import com.macfaq.io.*;
public class SocketTyper {
public static void main(String[] args) {
if (args.length == 0) {
System.err.println("Usage: java SocketTyper url1 url2 ...");
return;
}
for (int i = 0; i < args.length; i++) {
if (args.length > 1) {
System.out.println(args[i] + ":");
}
try {
URL u = new URL(args[i]);
if (!u.getProtocol().equalsIgnoreCase("http")) {
System.err.println("Sorry, " + u.getProtocol() +
" is not yet supported.");
break;
}
String host = u.getHost();
int port = u.getPort();
String file = u.getFile();
// default port
if (port <= 0) port = 80;
Socket s = new Socket(host, port);
String request = "GET " + file + " HTTP/1.0\r\n"
+ "User-Agent: MechaMozilla\r\nAccept: text/*\r\n\r\n";
// This next line is problematic on non-ASCII systems
byte[] b = request.getBytes();
OutputStream out = s.getOutputStream();
InputStream in = s.getInputStream();
out.write(b);
out.flush();
StreamCopier.copy(in, System.out);
in.close();
out.close();
s.close();
}
catch (MalformedURLException e) {System.err.println(e);}
catch (IOException e) {System.err.println(e);}
}
}
}
For example, when
SocketTyper
connects to http://www.oreilly.com/, here is what you see:% java SocketTyper http://www.oreilly.com/
HTTP/1.0 200 OK
Server: WN/1.15.1
Date: Sun, 09 Aug 1998 20:05:03 GMT
Last-modified: Fri, 07 Aug 1998 23:44:36 GMT
Content-type: text/html
Title: www.oreilly.com -- Welcome to O'Reilly & Associates!
Link: <mailto:webmaster@ora.com>; rev="Made"
<HTML>
<HEAD>
<META name="keywords" content="computer books, technical books, UNIX, unix,
Perl, Java, Linux, Internet, Web, C, C++, Windows, Windows NT, Security,
Sys Admin, System Administration, Oracle, design, graphics, online books,
online courses, Perl Conference, Web-based training, Software, open source,
free software">
Notice the header lines you didn't see in Example 5-1. When you use the
URL
class to download a web page, the associated protocol handler never shows you the HTTP header.Server Sockets
There are two ends to each connection: the client, which initiates the connection, and the server, which responds to the connection. So far, we've only discussed the client side and assumed that a server existed out there for the client to talk to. To implement a server, you need to write a program that waits for other hosts to connect to it. A server socket binds to a particular port on the local machine (the server); once it has successfully bound to a port, it listens for incoming connection attempts from remote machines (the clients). When the server detects a connection attempt, it accepts the connection. This creates a socket between the two machines over which the client and the server communicate.
Many clients can connect to a port on the server simultaneously. Incoming data is distinguished by the port to which it is addressed and the client host and port from which it came. The server can tell for which service (like HTTP or FTP) the data is intended by inspecting the port. It knows where to send any response by looking at the client address and port stored with the data.
No more than one server socket can listen to a particular port at one time. Therefore, since a server may need to handle many connections at once, server programs tend to be heavily multithreaded. Generally, the server socket listening on the port only accepts the connections. It passes off the actual processing of each connection to a separate thread. Incoming connections are stored in a queue until the server can accept them. On most systems, the default queue length is between 5 and 50. Once the queue fills up, further incoming connections are refused until space in the queue opens up.
The
java.net.ServerSocket
class represents a server socket. Three constructors let you specify the port to bind to, the queue length for incoming connections, and the IP address:public ServerSocket(int port) throws IOException
public ServerSocket(int port, int backlog) throws IOException
public ServerSocket(int port, int backlog, InetAddress bindAddr)
throws IOException
Normally, you specify only the port you want to listen on:
try {
ServerSocket ss = new ServerSocket(80);
}
catch (IOException e) {System.err.println(e);}
When you create a
ServerSocket
object, it attempts to bind to the port on the local host given by the port argument. If another server socket is already listening to the port, then ajava.net.BindException
, a subclass ofIOException
, is thrown. No more than one process or thread can listen to a particular port at a time. This includes non-Java processes or threads. For example, if there's already an HTTP server running on port 80, you won't be able to bind to port 80. On Unix systems (but not Windows or the Mac) your program must be running as root to bind to a port between 1 and 1023.0 is a special port number. It tells Java to pick an available port. You can then find out what port it's picked with the
getLocalPort()
method:public int getLocalPort()
This is useful if the client and the server have already established a separate channel of communication over which the chosen port number can be communicated. For example, the FTP protocol uses two sockets. The initial connection is made by the client to the server to send commands. One of the commands sent tells the server the port number on which the client is listening. The server then connects to the client on this port to send data.
Once you have a
ServerSocket
, you need to wait for incoming connections. You do this by calling theaccept()
method, which blocks until a connection attempt occurs and then returns aSocket
that you can use to communicate with the client. Theclose()
method terminates theServerSocket
.public Socket accept() throws IOException
public void close() throws IOException
That's pretty much all there is, except for a few methods dealing with socket options and some other details. In particular, there aren't methods for getting input and output streams. Instead,
accept()
returns aSocket
object: you call theSocket
'sgetInputStream()
orgetOutputStream()
method. For example:try {
ServerSocket ss = new ServerSocket(2345);
Socket s = ss.accept();
OutputStream out = s.getOutputStream();
// Send data to the client.
s.close();
}
catch (IOException e) {System.err.println(e);}
Notice in this example, I closed the
Socket
s
, not theServerSocket
ss
.ss
is still bound to port 2345. You get a new socket for each connection and reuse the server socket. For example, the next code fragment repeatedly accepts connections:try {
ServerSocket ss = new ServerSocket(2345);
while (true) {
Socket s = ss.accept();
OutputStream out = s.getOutputStream();
// send data to the client
s.close();
}
}
catch (IOException e) {System.err.println(e);}
The program in Example 5-5 reads a port number from the command line. It listens on that port for incoming connections. When it detects one, it answers back with the client's address and port and its own. Then it closes the connection.
Example 5-5:
The HelloServer Programimport java.net.*;
import java.io.*;
public class HelloServer {
public final static int defaultPort = 2345;
public static void main(String[] args) {
int port = defaultPort;
try {
port = Integer.parseInt(args[0]);
}
catch (Exception e) {}
if (port <= 0 || port >= 65536) port = defaultPort;
try {
ServerSocket ss = new ServerSocket(port);
while (true) {
try {
Socket s = ss.accept();
String response = "Hello " + s.getInetAddress() + " on port "
+ s.getPort() + "\r\n";
response += "This is " + s.getLocalAddress() + " on port "
+ s.getLocalPort() + "\r\n";
OutputStream out = s.getOutputStream();
out.write(response.getBytes());
out.flush();
s.close();
}
catch (IOException e) {}
}
}
catch (IOException e) {System.err.println(e);}
}
}
Here's some output from our server. The server is running on utopia.poly.edu. The client is connecting from titan.oit.unc.edu. Note how the port from which the connection comes changes each time; like most client programs, the telnet program picks a random local port for outgoing connections:
% telnet utopia.poly.edu 2545
Trying 128.238.3.21...
Connected to utopia.poly.edu.
Escape character is '^]'.
Hello titan.oit.unc.edu/152.2.22.14 on port 50361
This is utopia.poly.edu/128.238.3.21 on port 2545
Connection closed by foreign host.
% telnet utopia.poly.edu 2545
Trying 128.238.3.21...
Connected to utopia.poly.edu.
Escape character is '^]'.
Hello titan.oit.unc.edu/152.2.22.14 on port 50362
This is utopia.poly.edu/128.238.3.21 on port 2545
Connection closed by foreign host.
URLViewer
Example 5-6 is an improved version of the
URLViewer
you first encountered in Chapter 2. This is a simple application that provides a window in which you can view the contents of a URL. It assumes that those contents are more or less ASCII text. (In future chapters, I'll remove that restriction.) Figure 5-1 shows the result. Our application has a text area in which the user can type a URL, a Load button that the user uses to load the specified URL, and aStreamedTextArea
component that displays the text from the URL. Each of these corresponds to a field in theURLViewer
class.
Figure 5-1.
The URLViewer
Example 5-6:
The URLViewer Programimport java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import com.macfaq.awt.*;
import com.macfaq.io.*;
public class URLViewer extends Frame
implements WindowListener, ActionListener {
TextField theURL = new TextField();
Button loadButton = new Button("Load");
StreamedTextArea theDisplay = new StreamedTextArea();
public URLViewer() {
super("URL Viewer");
}
public void init() {
this.add("North", theURL);
this.add("Center", theDisplay);
Panel south = new Panel();
south.add(loadButton);
this.add("South", south);
theURL.addActionListener(this);
loadButton.addActionListener(this);
this.addWindowListener(this);
this.setLocation(50, 50);
this.pack();
this.show();
}
public void actionPerformed(ActionEvent evt) {
try {
URL u = new URL(theURL.getText());
InputStream in = u.openStream();
OutputStream out = theDisplay.getOutputStream();
StreamCopier.copy(in, out);
in.close();
out.close();
}
catch (MalformedURLException ex) {theDisplay.setText("Invalid URL");}
catch (IOException ex) {theDisplay.setText("Invalid URL");}
}
public void windowClosing(WindowEvent e) {
this.setVisible(false);
this.dispose();
}
public void windowOpened(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public static void main(String args[]) {
URLViewer me = new URLViewer();
me.init();
}
}
The
URLViewer
class itself extendsFrame
. An alternative would have been to extendPanel
, which would have allowedURLViewer
objects to be embedded in other containers. However, this application seemed big enough to justify exclusive use of a window.URLViewer
implements theWindowListener
interface to enable the user to close the window by clicking in the close box. Only thewindowClosing()
method is nontrivial. The other six window methods are do-nothing methods required to satisfy the contract of theWindowListener
interface.The
init()
method builds the interface and displays the window. This is invoked by themain()
method, which constructs a newURLViewer
object. The constructor is quite simple, merely passing the title of the frame to the superclass constructor.The streamed text area is filled when the user clicks the Load button or hits Return inside the URL text field. The
URLViewer
object listens to both of these components. TheURLViewer
'sactionPerformed()
method constructs a URL from the text in the text field, then opens an input stream from the URL in the text field. Next,StreamCopier
from Chapter 3, Input Streams pours the data from the URL's input stream into the text area's output stream. When that's finished, both streams are closed.Back to: Java I/O
O'Reilly Home |
O'Reilly Bookstores |
How to Order |
O'Reilly Contacts
International |
About O'Reilly |
Affiliated Companies
© 2001, O'Reilly & Associates, Inc.
webmaster@oreilly.com