Java I/O库的设计原则
Java的I/O库提供了一个称做链接的机制,可以将一个流与另一个流首尾相接,形成一个流管道的链接。这种机制实际上是一种被称为Decorator(装饰)设计模式的应用。
通过流的链接,可以动态的增加流的功能,而这种功能的增加是通过组合一些流的基本功能而动态获取的。
我们要获取一个I/O对象,往往需要产生多个I/O对象,这也是Java I/O库不太容易掌握的原因,但在I/O库中Decorator模式的运用,给我们提供了实现上的灵活性。
I/O流的链接
Reader和Writer
Java程序语言使用Unicode来表示字符串和字符。
Reader和Writer这两个抽象类主要用来读写字符流。
java.io包中Reader的类层次
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
类 Reader
java.lang.Object
java.io.Reader
所有已实现的接口:
Closeable, Readable
直接已知子类:
BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader
public abstract class Reader
extends Object
implements Readable, Closeable
用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。
从以下版本开始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
类 BufferedReader
java.lang.Object
java.io.Reader
java.io.BufferedReader
所有已实现的接口:
Closeable, Readable
直接已知子类:
LineNumberReader
public class BufferedReader
extends Reader
从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
通常,Reader 所作的每个读取请求都会导致对基础字符或字节流进行相应的读取请求。因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。例如,
BufferedReader in
= new BufferedReader(new FileReader("foo.in"));
将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。
可以对使用 DataInputStream 进行按原文输入的程序进行本地化,方法是用合适的 BufferedReader 替换每个 DataInputStream。
从以下版本开始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
类 InputStreamReader
java.lang.Object
java.io.Reader
java.io.InputStreamReader
所有已实现的接口:
Closeable, Readable
直接已知子类:
FileReader
public class InputStreamReader
extends Reader
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,否则可能接受平台默认的字符集。
每次调用 InputStreamReader 中的一个 read() 方法都会导致从基础输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从基础流读取更多的字节,使其超过满足当前读取操作所需的字节。
为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:
BufferedReader in
= new BufferedReader(new InputStreamReader(System.in));
从以下版本开始:
JDK1.1
java.io包中Writer的类层次
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
类 Writer
java.lang.Object
java.io.Writer
所有已实现的接口:
Closeable, Flushable, Appendable
直接已知子类:
BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter
public abstract class Writer
extends Object
implements Appendable, Closeable, Flushable
写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。
从以下版本开始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
类 BufferedWriter
java.lang.Object
java.io.Writer
java.io.BufferedWriter
所有已实现的接口:
Closeable, Flushable, Appendable
public class BufferedWriter
extends Writer
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性 line.separator 定义。并非所有平台都使用新行符 ('\n') 来终止各行。因此调用此方法来终止每个输出行要优于直接写入新行符。
通常 Writer 将其输出立即发送到基础字符或字节流。除非要求提示输出,否则建议用 BufferedWriter 包装所有其 write() 操作可能开销很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如,
PrintWriter out
= new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
将缓冲 PrintWriter 对文件的输出。如果没有缓冲,则每次调用 print() 方法会导致将字符转换为字节,然后立即写入到文件,而这是极其低效的。
从以下版本开始:
JDK1.1
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
类 OutputStreamWriter
java.lang.Object
java.io.Writer
java.io.OutputStreamWriter
所有已实现的接口:
Closeable, Flushable, Appendable
直接已知子类:
FileWriter
public class OutputStreamWriter
extends Writer
OutputStreamWriter 是字符流通向字节流的桥梁:使用指定的 charset 将要向其写入的字符编码为字节。它使用的字符集可以由名称指定或显式给定,否则可能接受平台默认的字符集。
每次调用 write() 方法都会针对给定的字符(或字符集)调用编码转换器。在写入基础输出流之前,得到的这些字节会在缓冲区累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递到此 write() 方法的字符是未缓冲的。
为了达到最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中以避免频繁调用转换器。例如:
Writer out
= new BufferedWriter(new OutputStreamWriter(System.out));
代理对 是一个字符,它由两个 char 值序列表示:高 代理项的范围为 '\uD800' 到 '\uDBFF',它后面跟着范围为 '\uDC00' 到 '\uDFFF' 的低 代理项。如果由代理项对表示的字符无法由给定的字符集编码,则把依赖于字符集的替代序列 写入输出流。
错误代理元素 指的是后面不跟低代理项的高代理项,或前面没有高代理项的低代理项。尝试写入包含错误代理元素的字符流是非法的。写入错误代理元素时,此类实例的行为是不确定的。
从以下版本开始:
JDK1.1
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo1:通过字符流将字符串写入指定文件。
-------------------------------------------------------------------------------
1
import
java.io.
*
;
2
3
public
class
CharStream
{
4
5
public
static
void
main(String[] args)
throws
Exception
{
6
7
FileOutputStream fos
=
new
FileOutputStream(
"
write.txt
"
);
8
OutputStreamWriter osw
=
new
OutputStreamWriter(fos);
9
BufferedWriter bw
=
new
BufferedWriter(osw);
10
11
bw.write(
"
http://www.blogjava.com
"
);
12
bw.close();
13
}
14
15
}
-------------------------------------------------------------------------------
运行结果:字符串"http://www.blogjava.com"被写入write.txt 文件中。
-------------------------------------------------------------------------------
Demo2:通过字符流将字符串写入指定文件,同时读取字符流。
-------------------------------------------------------------------------------
1
import
java.io.
*
;
2
3
public
class
CharStream
{
4
5
public
static
void
main(String[] args)
throws
Exception
{
6
7
FileOutputStream fos
=
new
FileOutputStream(
"
write.txt
"
);
8
OutputStreamWriter osw
=
new
OutputStreamWriter(fos);
9
BufferedWriter bw
=
new
BufferedWriter(osw);
10
11
bw.write(
"
http://www.blogjava.com
"
);
12
bw.close();
13
14
FileInputStream fis
=
new
FileInputStream(
"
write.txt
"
);
15
InputStreamReader isr
=
new
InputStreamReader(fis);
16
BufferedReader br
=
new
BufferedReader(isr);
17
System.out.println(br.readLine());
18
br.close();
19
}
20
21
}
-------------------------------------------------------------------------------
运行结果:字符串"http://www.blogjava.com"被写入write.txt 文件中。
然后被读取出来。
-------------------------------------------------------------------------------
Demo3:通过字符流接收数据,然后输出到控制台。
-------------------------------------------------------------------------------
1
import
java.io.
*
;
2
3
public
class
CharStream
{
4
5
public
static
void
main(String[] args)
throws
Exception
{
6
7
InputStreamReader isr
=
new
InputStreamReader(System.in);
8
BufferedReader br
=
new
BufferedReader(isr);
9
10
String strLine
=
null
;
//
定义一个对象后最好先将它初始化
11
while
((strLine
=
br.readLine())
!=
null
)
{
12
System.out.println(strLine);
13
}
14
15
br.close();
16
}
17
18
}
-------------------------------------------------------------------------------
运行结果:控制台输出输入的内容。
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo4:通过字符流接收数据,然后输出到控制台,同时将输入内容写入
指定的文件中。
-------------------------------------------------------------------------------
1
import
java.io.
*
;
2
3
public
class
CharStream
{
4
5
public
static
void
main(String[] args)
throws
Exception
{
6
7
FileOutputStream fos
=
new
FileOutputStream(
"
write1.txt
"
);
8
OutputStreamWriter osw
=
new
OutputStreamWriter(fos);
9
BufferedWriter bw
=
new
BufferedWriter(osw);
10
11
InputStreamReader isr
=
new
InputStreamReader(System.in);
12
BufferedReader br
=
new
BufferedReader(isr);
13
14
String strLine
=
null
;
//
定义一个对象后最好先将它初始化
15
16
while
(
!
(strLine
=
br.readLine()).equals(
"
exit
"
))
{
17
System.out.println(strLine);
18
bw.write(strLine);
19
bw.write(
"
\n
"
);
20
}
21
22
bw.close();
23
br.close();
24
}
25
26
}
-------------------------------------------------------------------------------
运行结果:控制台输出输入的内容,同时输入的内容被写入指定的文件中。
-------------------------------------------------------------------------------
posted on 2006-08-24 20:01
CoderDream 阅读(1260)
评论(0) 编辑 收藏 所属分类:
Java基础知识