Java网络编程之URI、URL研究专题六
Authority = http://www.javajeff.com
Default port = 80
File = /articles/articles.html
Host = http://www.javajeff.com
Path = /articles/articles.html
Port = -1
Protocol = http
Query = null
Ref = null
User Info = null
<html>
<head>
<title>
Java Jeff - Articles
</title>
<meta http-equiv=Content-Type content="text/html;
charset=ISO-8859-1">
<meta name=author content="Jeff Friesen">
<meta name=keywords content="java, virtual machine">
<script language=JavaScript>
if (navigator.appName == "Netscape")
document.write ("<br>");
</script>
</head>
<body bgcolor=#000000>
<center>
<table border=1 cellpadding=5 cellspacing=0>
<tr>
<td>
<table cellpadding=0 cellspacing=0>
<tr>
<td>
<a href=informit/informit.html>
<img alt=InformIT border=0 src=informit.gif></a>
</td>
</tr>
</table>
</td>
<td align=middle>
<img src=title.gif><br>
<a href=../welcome/welcome.html>
<img alt="Welcome to Java Jeff!" border=0 src=jupiter.jpg>
</a><br>
<img src=../common/clear_dot.gif vspace=5><br>
<a href=../ads/ads.html>
<img alt="Welcome to Java Jeff!" border=0
rc=jupiter.jpg>
</td>
<td>
<table cellpadding=0 cellspacing=0>
<tr>
<td>
<a href=javaworld/javaworld.html>
<img alt=JavaWorld border=0 src=javaworld.gif></a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</center>
<br>
<font color=#ffffff>
<center>
Best viewed at a resolution of 1024x768 or higher.<br>
<img src=../common/clear_dot.gif vspace=5><br>
<i>
Copyright ? 2001-2002, Jeff Friesen. All rights
reserved.
</i>
<p>
<a href=../index.html>
<img alt=Back border=0 src=../common/back.gif></a>
</center>
</font>
</body>
</html>
在上面的信息中,输出标识符80是默认端口,HTTP是协议。上面给出的是输出的HTML页面的源代码。
URL的openStream()方法通常返回抽象的InputStream类的一个具体的子类所建立的对象的引用。这意味着你必须按字节次序读取资源数据,这种做法是恰当的,因为你不知道将要读取的数据是什么类型的。如果你事先知道要读取的数据是文本的,并且每一行以换行符(\n)结束,你就可以按行读取而不是按字节读取数据了。
下面的代码片断演示了把一个InputStream对象包装进java.io.InputStreamReader对象以从8位过渡到16位字符,把结果对象包装进java.io.BufferedReader对象以访问BufferedReader的readLine()方法,并调用readLine()方法从资源读取文本的所有行。
InputStream is = url.openStream ();
BufferedReader br = new BufferedReader (new InputStreamReader (is));
String line;
while ((line = br.readLine ()) != null)
System.out.println (line);
is.close ();
有时候按字节的次序读取数据并不方便。例如,如果资源是JPEG文件,那么获取一个图像处理过程并向该过程注册一个用户使用数据的方法更好。当图像完整下载后立即显示它并不困难。如果出现这种情况,你就有必要使用getContent()方法。
当调用getContent()方法时,它会返回某种对象的Object引用,而你可以调用该对象的方法(在转换成适当的类型后),采用更方便的方式检索数据。但是在调用该方法前,你必须使用instanceof验证对象的类型,防止类产生异常。
对于JPEG资源,getContent()返回一个对象,该对象的类实现了java.awt.Image.ImageProducer接口。下面的代码片断演示了使用instanceof验证对象是ImageProducer的,并进行了转换。接下来可以调用ImageProducer方法注册一个用户并初始化图像的使用过程。
URL url = new URL (args [0]);
Object o = url.getContent ();
if (o instanceof ImageProducer)
{
ImageProducer ip = (ImageProducer) o;
// ...
}
技巧
调用URL的equals(Object o)和sameFile(Object o)方法来决定两个URL是否相同。第一个方法包含了比较的片断,而第二个方法没有包含。你可以参阅SDK文档查找更多信息。
查看一下getContent()方法的源代码,你会找到openConnection().getContent()。此外,查看一下openStream()方法的源代码,你会发现openConnection().getInputStream()。每个方法都首先调用URL的openConnection()方法。
这个方法返回抽象的java.net.URLConnection类(描述与某些资源的连接)的一个子类建立的对象的引用。URLConnection的方法反映了资源和连接的细节信息,使我们能编写代码向资源写入信息。
列表5的URLDemo2源代码演示了openConnection(),以及调用一些URLConnection的方法。
列表5: URLDemo2.java
// URLDemo2.java
import java.io.*;
import java.net.*;
import java.util.*;
class URLDemo2
{
ublic static void main (String [] args) throws IOException
{
if (args.length != 1)
{
System.err.println ("usage: java URLDemo2 url");
return;
}
URL url = new URL (args [0]);
// 返回代表某个资源的连接的新的特定协议对象的引用
URLConnection uc = url.openConnection ();
// 进行连接
uc.connect ();
// 打印多种头部字段的内容
Map m = uc.getHeaderFields ();
Iterator i = m.entrySet ().iterator ();
while (i.hasNext ())
System.out.println (i.next ());
// 如果资源允许输入和输出操作就找出来
System.out.println ("Input allowed = " +uc.getDoInput ());
System.out.println ("Output allowed = " +uc.getDoOutput ());
}
}