包装类
例如DataOutputStream类提供了往各种输出流对象中写入各种数据的方法,但是它并不对应到具体的流设备,我们所要做的工作就是传递一个对应具体流设备的输出对象。完成类似DataOutputStream功能的类就是一个包装类,也叫过滤流类或处理流类。
DataOutputStream包装类的构造方法:
public DataOutputStream(OutputStream out):需要接受OutputStream类的参数
包装类也可以去包装另外一个包装类,即上面的构造函数的参数也可以是OutputStream类型的另外一种包装类。这样各个类连成一条链称为流栈,关闭流栈的最上层(最外层)的流对象,将会关闭流栈中的所有底层流对象。
应用程序调用包装类的各种方法,然后包装类中的方法再去调用它所包装的类中的方法,最终将数据写到目标设备上。
BufferedInputStream与BufferedOutputStream类
缓冲流为I/O流增加了内存缓冲区,增加缓冲区有两个基本目的:允许程序一次不只操作一个字节,这样提高了程序的性能;有了缓冲区,使得在流上执行skip、mark和reset方法都成为可能。
BufferedInputStream与BufferedOutputStream是java提供的两个缓冲区包装类,不管底层系统是否使用了缓冲区,这两个类都会在自己的实例对象中创建缓冲区。
底层系统创建的缓冲区直接目标设备交换数据,而包装类创建的缓冲区需要调用那个包装类包装的输出流对象,将数据写入到目标设备或底层缓冲区中。或者是调用那个包装类包装的输入流对象,从目标设备或底层缓冲区中读取数据到包装类的缓冲区中。底层缓冲区一次性写入或读取大量的数据,而包装类的缓冲区将一次读取的那一个数据先放到包装类的缓冲区中,然后在输出。这可以提高效率,在进行字符转为字符串的操作中要用到包装类的缓冲区。
创建BufferedInputStream的实例对象可以实现输入缓冲区,有两个主要的构造函数:
BufferedInputStream(InputStream in):创造一个有32个字节的缓冲区
BufferedInputStream(InputStream in,int size):按大小创建缓冲区,该大小通常为内存、磁盘等一次读写所能处理的数据的整数倍。
BufferedOutputStream两个主要的构造函数:
BufferedOutputStream(OutputStream out):创建一个512个字节的输出缓冲区
BufferedOutputStream(OutputStream out,int size):按指定的大小创建输出缓冲区
与字节的输入输出相对应有:BufferedReader和BufferedWriter类。BufferedReader的readLine方法可以一次读取一行文本,BufferedWriter的newLine方法可以像向字符流中写入不同操作系统下的换行符。
DataOutputStream与DataInputStream类
DataOutputStream类提供了三个写入字符串的的方法:
——public final void writeBytes(String s):
——public final void writeChars(String s)
——public final void writeUTF(String s)
因为java采用Unicode编码,每个字符占两个字节,writeBytes只是将每个字符的低字节写入目标设备中。writeChars方法将每个字符的两个字节都写入目标设备中。writeUTF方法将字符串按UTF编码写入,写入的带有长度头,前两个字节表示将字符串编码后的长度。
在DataInputStream中只有readUTF方法与之对应,而没有readBytes和readChars方法,是因为流中无法确定字符串的长度,而writeUTF方法写入的数据表明了长度。
PrintStream类
PrintStream类提供了一系列的print和println方法,可以将基本数据类型的数据格式 化成字符串输出。格式化输出就是将数据按字符串的格式输出。
PrintStream类的三个构造函数:
PrintStream(OutputStream out)不会自动刷新
PrintStream(OutputStream out,boolean autoflush)第二个参数表示自动刷新,当输出的字符串中出现/n时,是否自动刷新。
PrintStream(OutputStream out,boolean autoflush,String encoding) 第三个参数表示字符集。
与PrintStream对应的PrintWriter类,即使到了文本换行符(/n),也设置了自动刷新,PrintWriter也不会自动清空缓冲区,只有调用println方法才会进行刷新,清空缓冲区。PrintWriter类的println方法能根据操作系统的不同而生成相应的文本换行表示符。
ObjectInputStream与ObjectOutputStream类
ObjectInputStream与ObjectOutputStream类这两个包装类,用于从底层输入流中读取对象类型的数据和将对象类型的数据写入到底层输出流。
ObjectInputStream与ObjectOutputStream类所读写的对象必须实现了Serializable(序列化)接口。对象中的transient(暂时)和static类型的成员变量不会被读取与写入。
字节流与字符流的转换
InputStreamReader和OutputStreamWriter,是两个用于将字节流流转换成字符流来读写的两个包装类,InputStreamReader可以将一个字节流中的字节解码成字节符后读取,OutputStreamWriter将字符编码成字节后写入到一个字节流中。
InputStreamReader的两个主要构造函数:
——InputStreamReader(InputStream in)
——InputStreamReader(InputStream in,String CharsetName)
OutputStreamWriter的两个主要构造函数:
——OutputStreamWriter(OutputStream out)
——OutputStreamWriter(OutputStream out,String CharsetName )
避免频繁地在字节与字符间进行转换,最好不要直接使用InputStreamReader和OutputStreamWriter类来读写数据,应尽量使用BufferedWriter类包装OutputStreamWriter类,用BufferedReader来包装InputStreamReader。
java程序与其他进程的数据通信
在java程序中可以用Process类的实例对象来表示子进程,子进程的标准输入和输出不再连接到键盘和显示器,而是以管道流的形式连接到父进程的一个输出流和输入流对象上。关掉父进程,子进程仍会活着。注意调用Process类的destroy方法销毁。
调用Process类的getOutputStream和getInputStream方法可以获得连接到子进程的输出流和输入流对象。子进程从标准输入流读取到的内容就是父进程通过输出流对象写入到管道流中的数据;子进程写入到的标准输出的数据通过管道传到父进程的输入流对象中,父进程从输入流中读取的数据就是子进程写入的数据。
变成举例:在TestInOut类中启动java.exe命令执行另外一个MyTest类,TestInOut和MyTest通过进程间的管道相互传递数据。(TestInOut相当于父进程,而MyTest相当于子进程):
import java.io.*;
public class TestInOut implements Runnable{
Process p=null;
public TestInOut()
{
try
{
p=Runtime.getRuntime().exec("java MyTest");
new Thread(this).start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
TestInOut io=new TestInOut();
io.send();
}
public void send()
{
try
{
OutputStream out=p.getOutputStream();
while(true)
{
out.write("help/n".getBytes());
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void run() //读子进程中写入的数据
{
try
{
InputStream in=p.getInputStream();
BufferedReader bfr=new BufferedReader(
new InputStreamReader(in));
while(true)
{
String strLine=bfr.readLine();
if(strLine!=null)
{
System.out.println(strLine);
}
else
return;
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
import java.io.*;
public class MyTest {
public static void main(String[] args) {
String strLine=null;
BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in));
while(true)
{
try
{
strLine=bfr.readLine();
}
catch(Exception e)
{
e.printStackTrace();
}
if(strLine!=null)
{
System.out.println("hi:"+strLine);
}
else
return;
}
}
}