学习目标
–理解Java I/O系统
–熟练使用java.io包中的相关类与接口进行I/O编程
流的概念
Java程序通过流来完成输入/输出。流是生产或消费信息的抽象。流通过Java的输入/输出系统与物理设备链接。尽管与它们链接的物理设备不尽相同,所有流的行为具有同样的方式。这样,相同的输入/输出类和方法适用于所有类型的外部设备。这意味着一个输入流能够抽象多种不同类型的输入:从磁盘文件,从键盘或从网络套接字。同样,一个输出流可以输出到控制台,磁盘文件或相连的网络。流是处理输入/输出的一个洁净的方法,例如它不需要代码理解键盘和网络的不同。Java中流的实现是在java.io包定义的类层次结构内部的。
•输入/输出时,数据在通信通道中流动。所谓“数据流(stream)”指的是所有数据通信通道之中,数据的起点和终点。信息的通道就是一个数据流。只要是数据从一个地方“流”到另外一个地方,这种数据流动的通道都可以称为数据流。
•输入/输出是相对于程序来说的。程序在使用数据时所扮演的角色有两个:一个是源,一个是目的。若程序是数据流的源,即数据的提供者,这个数据流对程序来说就是一个“输出数据流”(数据从程序流出)。若程序是数据流的终点,这个数据流对程序而言就是一个“输入数据流”(数据从程序外流向程序)
•在java.io包中提供了60多个类(流)。
•从功能上分为两大类:输入流和输出流。
•从流结构上可分为字节流(以字节为处理单位或称面向字节)和字符流(以字符为处理单位或称面向字符)。
•字节流的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。字符流是Java1.1版后新增加的以字符为单位进行输入输出处理的流,字符流输入输出的基础是抽象类Reader和Writer
•Java 2 定义了两种类型的流:字节流和字符流。字节流(byte stream)为处理字节的输入和输出提供了方便的方法。例如使用字节流读取或写入二进制数据。字符流(character stream)为字符的输入和输出处理提供了方便。它们采用了统一的编码标准,因而可以国际化。当然,在某些场合,字符流比字节流更有效。
•字节流类(Byte Streams)字节流类用于向字节流读写8位二进制的字节。一般地,字节流类主要用于读写诸如图象或声音等的二进制数据。
•字符流类(Character Streams)字符流类用于向字符流读写16位二进制字符。
•两种基本的流是:输入流(Input Stream)和输出流(Output Stream)。可从中读出一系列字节的对象称为输入流。而能向其中写入一系列字节的对象称为输出流。
•读数据的逻辑为:
open a stream
while more information
read information
close the stream
•写数据的逻辑为:
open a stream
while more information
write information
close the stream
参见程序InputStreamTest1.java
•该程序用read()来输入和显示文本文件的内容,该文件名以命令行形式指定。注意try/catch块处理程序运行时可能发生的两个错误——未找到指定的文件或用户忘记包括文件名了。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class InputStreamTest1
{
public static void main(String[] args) throws IOException
{
InputStream is=new FileInputStream("d:/hello.txt");
byte[] buffer=new byte[200];
int length=0;
while(-1!=(length=is.read(buffer,0,200))){
String str=new String(buffer,0,length);
System.out.println(str);
}
is.close();
}
}
参见程序OutputStreamTest1.java
•该程序用write()来输出和显示文本文件的内容,该文件名以命令行形式指定。注意try/catch块处理程序运行时可能发生的两个错误——未找到指定的文件或用户忘记包括文件名了。
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class OutputStream1
{
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
OutputStream os=new FileOutputStream("1.txt");
BufferedOutputStream bos=new BufferedOutputStream(os);
bos.write("www.sina.com.cn".getBytes());
bos.close();
os.close();
}
}
•尽管字节流提供了处理任何类型输入/输出操作的足够的功能,它们不能直接操作Unicode字符。既然Java的一个主要目的是支持“只写一次,到处运行”的哲学,包括直接的字符输入/输出支持是必要的。本节将讨论几个字符输入/输出类。字符流层次结构的顶层是Reader 和Writer 抽象类。我们将从它们开始。
•由于Java采用16位的Unicode字符,因此需要基于字符的输入/输出操作。从Java1.1版开始,加入了专门处理字符流的抽象类Reader和Writer,前者用于处理输入,后者用于处理输出。这两个类类似于InputStream和OuputStream,也只是提供一些用于字符流的规定,本身不能用来生成对象。
参照程序StreamTest.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class StreamTest
{
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
FileOutputStream fos=new FileOutputStream("file.txt");
OutputStreamWriter os=new OutputStreamWriter(fos);
BufferedWriter bw=new BufferedWriter(os);
bw.write("http://www.google.cn");
bw.write("\n");
bw.write("http://www.baidu.com");
bw.close();
FileInputStream fis=new FileInputStream("file.txt");
InputStreamReader in=new InputStreamReader(fis);
BufferedReader br=new BufferedReader(in);
System.out.println(br.readLine());
System.out.println(br.readLine());
System.out.println(br.readLine());
br.close();
//
// String str=br.readLine();
// while(null!=str)
// {
// System.out.println(str);
// str=br.readLine();
// }
//
}
}
•该程序用write()来输出和显示读取字符的内容,该文件名以命令行形式指定。注意try/catch块处理程序运行时可能发生的两个错误——未找到指定的对象。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class StreamTest2
{
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
String str;
while(null!=(str=br.readLine()))
{
System.out.println(str);
}
}
}
该程序用输入流跟缓冲流读写命令行输入的数据,然后在显示出来。