第八章
流
输入/输出流的分类
Java.io包中定义了多个流的类型(类或抽象类)来实现输入/输出功能;可以从不同的角度对其进行分类:
按数据流的方向不同可以分为输入流和输出流
按处理数据单位不同可以分为字节流和字符流
按照功能不同可以分为节点流和处理流
J2SDK所提供的所有流类型位于包java.io内都分别继承自以下四种抽象类型.
|
字节流
|
字符流
|
输入流
|
InputStream
|
Reader
|
输出流
|
OutputStream
|
Writer
|
输入和输出相对于程序说
节点流可以从一个特定的数据源(节点)读写数据(如:文件,内存)
处理流是连接在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能.
InputStream
继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(8bit);
InputStream
InputStream的基本方法
Int read() throws IOException 读取一个字节并以整数的形式返回(0~255),如果返回-1已到输入流的末尾
Int read(bute[] buffer) throws IOException 读取一系列字节并存储到一个数组buffer,返回实际读取的字节数,如果读取前已到输入流的末尾返回-1
Int read(byte[] buffer,int offset,int lengt throws IOException) 读取length个字节,并存储到一个字节数组buffer,从length位置开始,返回实际读取的字节数,如果读取前已到输入流的末尾返回-1
Void close() throws IOException 关闭流释放内存资源
Long skip(long n) throws IOException 跳过n个字节不读,返回实际跳过的字节数
OutputStream
继承自OutputStream的流是用于程序中输出数据,且数据的单位为字节(8bit);
FileOutputStream
OutputStream
PipedOutputStream
ByteArrayOutputStream
ObjectOutputStream
FilterOutputStream
DataOutputStream
BufferedOutputStream
PrintStream
OutputStream的基本方法
Void write(int b) throws IOException 向输出流中写入一个字节数据,该字节数据为参数b的低8位
Void write(byte[] b) throws IOException 将一个字节类型的数组中的数据写入输出流
Void write(byte[] b,int off,int len throws IOException) 将一个字节类型的数组中的数据从指定位置off开始的len个字节写入到输出流
Void flush() throws IOException 将缓冲区中缓冲的数据全部写出到目的地
Void close() throws IOException 关闭流释放内存资源
Reader
继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符(16bit)
Reader
BufferedReader LineNumberReader
CharArrayReader
InputStreamReader FileReader
FilterReader PushbackReader
PipedReaderu
StringReader
Reader的基本方法
int read() throws IOException 读取一个字符并以整数的形式返回(0~255),如果返回-1已到输入流的末尾
int read(char[] cbuf) throws IOException 读取一系列字符并存储到一个数组buffer,返回实际读取的字符数,如果读取前已到输入路的末尾返回-1
int read(char[] cbuf,int offset,int length throws IOException) 读取length个字符并存储到一个数组buffer,从length位置开始返回实际读取的字符数,如果读取前以到输入流的末尾返回-1
void close() throws IOException 关闭流释放内存资源
long skip(long n) throws IOException 跳过n个字符不读,返回实际跳过的字节数
writer
继承自writer的流都是用于程序中输入数据,且数据的单位为字符(16bit);
BufferedWriter
Writer
CharArrayWriter
OutputStreamReader FileWriter
FilterWriter
PipedWriter
StringWriter
Writer的基本方法
Void write (int c) throws IOException 向输出流中写入一个字符数据,该字节数据为参数b的低16位
Void write(char[] cbuf) throws IOException 将一个字符类型的数组中的数据写入输出
Void write(char[] cbuf,int offset,int length throws IOException) 将一个字符类型的数组中的指定位置offset开始的length个字符写入到输出流
Void write(String string ) throws IOException 将一个字符串中的字符写入到输出流
Void flush() throws IOException 将输出流中缓冲的数据全部写出到目的地.
Void close() throws IOException 关闭流释放内存资源
访问文件
FileInputStream和FileOutputStream分别继承自InputStream和OutputStream用于向文件中输入和输出字节
FileInputStream FileOutputStream的常用构造方法:
FileInputStream(String name) throws FileNotFoundException
fileInputStream(File file) throws FileNotFoundException
FileOutputStream(String name) throws FileNotFoundException
FileOutputStream(File file) throws FileNotFoundException
FileOutputStream(File file,Boolean append throws FileNoFoundException)
FileInputStream FileOutputStream类支持其父类InputStream和OutputStream所提供的数据读写方法
注意:在实例化FileInputStream和FileOutputStream流时要用try-catch语句以处理其可能抛出的FileNotFoundException.
在读写数据时也要用try-catch语句以处理可能抛出的IOException
FileNotFoundException 是IOException的子类
Eg:
Import java.io.*;
Public class TestFileInputStream{
Public static void main(String[] args){
Int b=0;
FileInputStream in=null;
Try{
In =new FileInputStream(“d:\\share\\java\\io\\TestFileInputStream.java”);
}catch(FileNotFoundException e){
System.out.println(“找不到指定文件”);
System.exit(-1);
}
Try{
Long num=0;
While((b=in.read())!=-1){
System.out.print((char)b);
Num++;
}
In.close();
System.out.println();
System.out.println(“共读取了”+num+”个字节”);
}catch(IOException e1){
System.out.println(“文件读取错误”);
System.exit(-1);
}
}
}
Import java.io.*;
Public class TestFileOutputStream{
Public static void main(String[] args){
Int b=0;
FileInputStream in=null;
FileOutputStream out=null;
Try{
In =new FileInputStream(“d:/java/HelloWorld.java”);
Out=new FileOutputStream(“d:/java/io/HW.java”);
While((b=in.read())!=-1){
Out.write(b);
}
In.close();
Out.close();
}catch(FileNotFoundException e2){
System.out.println(“找不到指定文件”);
System.exit(-1);
}catch(IOException e1){
System.out.println(“文件复制错误”);
System.exit(-1);
}
System.out.println(“文件已复制”);
}
}
Import java.io.*;
Public class TestFileReader{
Public static void main(String[] args){\
FileReader fr=null;
Int c=0;
Try{
Fr=new FileReader(“d:\\share\\java\\io\\TestFileReader.java”);
Int ln=0;
While((c=fr.read())!=-1){
System.out.print((char)c);
}
fr.close();
}catch(FileNotFoundException e){
System.out.println(“找不到指定文件”);
}catch(IOException e){
System.out.println(“文件读取错误”);
}
}
}
Import java.io.*;
Public class testFileWriter{
Public static void main(String[] args){
FileWriter fw=null;
Try{
Fw=new FileWriter(“d:\\bak\\unicode.dat”);
For(int c=0;c<=50000;c++){
Fw.write(c);
}
Fw.close();
}catch(IOException e1){
E1.printStackTrace();
System.out.println(“文件写入错误”);
System.exit(-1);
}
}
}
处理流类型
缓冲流
缓冲流要套接在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法.J2SDK提供了四种缓存流,常用构造方法为:
BufferedReader(Reader in)
BufferedReader(Reader in,int sz) //sz为自定义缓存区的大小
BufferedWriter(Writer out)
BufferedWriter(Writer out,int sz)
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in,int size)
BufferedOutputStream(OutputStream out)
BufferedOutputStream(OutputStream out,int size)
缓冲输入流支持其父类的mark和reset方法
BufferedReader提供了readLine方法用于读取一行字符串(以\r或\n分隔)
BufferedWriter 提供了newLine用于写入一个行分隔符
对于输出的缓冲流,写出的数据会先在内存中缓存,使用flush方法将会使内存中的数据立刻写出.
Eg
Import java.io.*;
Public class TestBufferStream1{
Public static void main(String[] args){
Try{
FileInputStream fis=new FileInputStream(“d:\\share\\java\\HelloWorld.java”);
BufferedInputStream bis=new BufferedInputStream(fis);
Int c=0;
System.out.println(bis.read());
System.out.println(bis.read());
Bis.mark(100);
For(int i=0;i<10&&(c=bis.read())!=-1;i++){
System.out.print((char)c+””);
}
System.out.println();
Bis.reset();
For(int i=0;i<10&&(c=bis.read())!=-1;i++){
System.out.print((char)c+””);
}
Bis.close();
}catch(IOException e){e.printStackTrace}
}
}
Import java.io.*;
Public class TestBufferStream2{
Public static void main(String[] args){
Try{
BufferedWriter bw=new BufferedWriter(new FileWriter(“d:\\share\\java\\dat2.txt”));
BufferedReader br=new BufferedReader(new FileReader(“d:\\share\\java\\dat2.txt”));
String s=null;
For(int i=1;i<=100;i++){
S=String.valueOf(Math.random());
Bw.write(s);
Bw.newLine();
}
Bw.flush();
While((s=br.readLine())!=null){
System.out.println(s);
}
Bw.close();
Br.close();
}catch(IOException e){e.printStackTrace();}
}
}
转换流
InputStreamReader 和OutputStreamWriter用于字节数据到字符数据之间的转换
InputStreamReader需要和InputStream套接
OutputStreamWriter需要和OutputStream套接
转换流在构造是可以指定其编码集合,例如:InputStream isr=new InputStreamReader(System.in,”ISO8859_1”)
Import java.io.*;
Public class TestTransForm1{
Public static void main(String[] args){
Try{
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream(“d:\\bak\\char.txt”));
Osw.write(“mircosoftibmsunapplehp”);
System.out.println(osw.getEncoding());
Osw.close();
Osw=new OutputStreamWriter(new FileOutputStream(“d:\\bak\\char.txt”,true),”ISO8859_1”);//追加.ISO8859_1西欧语言又叫latin-1
Osw.write(“mircosoftibmsunapplehp”);
System.out.println(osw.getEncoding());
Osw.close();
}catch(IOException e){e.printStackTrace;}
}
}
Import java.io.*;
Public class TesttransForm2{
Public static void main(String[] args){
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
String s=null;
Try{
S=br.readLine();
While(s!=null){
If(s.equalsIgnoreCase(“exit”)) break;//忽略大小写
System.out.println(s.toUpperCase());//转换成大写
S=br.readLine();
}
Br.close();
}catch(IOExcepton e){e.printStackTrace;}
}
}//阻塞
数据流
Int 4 long 8 float 4 double 8 boolean 1
字节
DateInputStream和DataOutputStream分别继承自InputStream和OutputStream,它属于处理流,需要分别套接在InputStream和OutputStream类型的节点流上
DataInputStream和DataOutputStream提供了可以存取与机器无关的java原始类型数据(如:int,double等)的方法
DataInputStream和DataOutputStream的构造方法为:DataInputStream(InputStream in)
DataOutputStream(OutputStream out)
Eg import java.io.*;
Public class TestDataStream{
Public static void main(String[] args){
ByteArrayOutputStream baos=new ByteArrayOutputStream();
DataOutputStream dos=new DataOutputStream(baos);
Try{
Dos.writeDouble(Math.random());
Dos.writeBoolean(true);
ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
System.out.println(bais.available());
DataInputStream dis=new DataInputStream(bais);
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
Dos.close();
Dis.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
Print
流
PrintWriter和PrintStream都属于输出流,分别针对于字符和字节.
PrintWriter和PrintStream提供了重载的print
Println方法用于多种数据类型的输出
PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息.
PrintWriter和PrintStream有自动flush功能.
PrintWriter(Writer out)
PrintWriter(Writer out,Boolean autoFlush)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out,boolean autoFlush)
PrintStream(OutputStream out)
PrintStream(OutputStream out,booleanautoFlush)
Eg import java.io.*;
Public class TestPrintStream1{
Public static void main(String[] args){
PrintStream ps=null;
Try{
FileOutputStream fos=new FileOutputStream(“d:\\bak\\log.dat”);
Ps=new PrintStream(fos);
}catch(IOException e){
e.printStackTrace();
}
If(ps!=null){
System.setOut(ps);
}
Int ln=0;
For(char c=0;c<=60000;c++){
System.out.print(c+” “);
If(ln++ >=100){System.out.println();ln=0;}
}
}
}
Import java.io.*;
Public class TestPrintStream2{
Public static void main(String[] args){
String filename=args[0];
If(filename!=null){list(filename,System.out);}
}
Public static void list(String f,PrintStream fs){
Try{
BufferedReader br=new BufferedReader(new FileReader(f));
String s=null;
While((s=br.readLine()!=null)){
Fs.println(s);
}
Br.close();
}catch(IOException e){
Fs.println(“无法读取文件”);
}
}
}
Import java.util.*;
Import java.io.*;
Public class TestPrintStream3{
Public static void main(String[] args){
String s=null;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
Try{
FileWriter fw=new FileWriter(“d:\\bak\\logfile.log”,true);
PrintWriter log=new PrintWriter(fw);
While((s=br.readLine())!=null){
If(s.equalsIgnoreCase(“exit”)) break;
System.out.println(s.toUpperCase());
Log.println(“-----”);
Log.println(s.toUpperCase());
Log.flush();
}
Log.println(“===”+new Data()+”===”);
Log.flush();
Log.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
Object
流
直接将object写入或读出
Transient关键字 透明的(可以用来修饰成员变量,序列化的时候不予考虑,为0)
Serializable接口 序列化(如果想把某个类的对象序列化必须实现)
Externalizable接口 外部化(标记序列对象可以序列化,自己控制序列化过程)
Eg
Import java.io.*;
Public class TestObjectIO{
Public static void main(String args[]) throws Exception{
T t=new T();
t.k=8;
FileOutputStream fos=new FileOutputStream(“d:/share/java/io/testobjectio.dat”);
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(t);
oos.flush();
oos.close();
FileInputStream fis=new FileInputStream(“d:/share/java/io/testobjectio.dat”);
ObjectInputStream ois=new ObjectInputStream(fis);
T tReaded =(T)ois.readObjecct();
System.out.println(tReaded.i+””+tReaded.j+””+tReader.d+””+tReaded.k);
}
}
Class T implements Serializable{
Int i=10;
Int j=9;
Double d=2.3;
Int k=15;
}