Java输入输出流(1)

来源:互联网 发布:光纤宽带连接不上网络 编辑:程序博客网 时间:2024/04/29 10:54

1. 串流设计概念

Java将输入/输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象。从应用角度来看,如果要将数据从来源取出,可以使用输入串流,如果要将数据写入目的地,可以使用输出串流。在java中,输入流代表对象为java.io.InputStream实例,输出串流代表对象为java.io.OutputStream实例

2. 串流继承架构
输入流继承架构

输入流InputStream的常用类继承架构

这里写图片描述
输出流OutputStream的常用继承架构

2.1. FileInputStream和FileOutputStream

FileInputStream是InputStream的子类,可以指定文件名创建实例,一旦创建文档就开启,接着就可以用来读取数据。主要操作InputStream的read()抽象方法,使之可以从文档中读取数据。
FileOutputStream是OutputStream的子类,可以指定文件名创建实例,一旦创建就开启,接着就可以用来写数据。主要操作OutputStream的write()抽象方法。使之可以写出数据至文档。
FileInputStream和FileOutputStream在读取、写入文档时,是以字节为单位,通常会使用一些高阶类加以打包,进行一些高阶的操作,如Scanner与PrintStream类。二者不用时都要使用close()关闭文档。下面使用file文件输入和输出的例子,主要作用是将in.txt文件中的内容完全读写到out.txt,包括汉字。

import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class FileStream{    public static void main(String[] args)     {        try        {            File directory = new File("source"); //当前文件夹建立source文件夹            String path =directory.getCanonicalPath();            System.out.printf("当前路径: %s%n",path);            FileInputStream file_in=new FileInputStream(path+"/in.txt");            FileOutputStream file_out=new FileOutputStream(path+"/out.txt");            int read;            byte[] b=new byte[file_in.available()];//新建一个字节数组            read=file_in.read(b);            while(read!=-1)            {                file_out.write(b,0,read);                  System.out.printf("ok");                read=file_in.read(b);//读取多个字节,如到输入流末尾则返回-1            }            file_in.close();//关闭流            file_out.close();        }catch (IOException e){            e.printStackTrace();        }       }}

输出:in.txt中的内容成功的被拷贝到out.txt

2.2. ByteArrayInputStream和ByteArrayFileOutputStream
字节数组输入流在内存中创建一个字节数组缓冲区,从输入流读取的数据保存在该字节数组缓冲区中。创建字节数组输入流对象有以下几种方式。
接收字节数组作

ByteArrayInputStream bArray = new ByteArrayInputStream(byte [] a);

另一种创建方式是接收一个字节数组,和两个整形变量 off、len,off表示第一个读取的字节,len表示读取字节的长度。

ByteArrayInputStream bArray = new ByteArrayInputStream(byte []a, int off, int len)

创建字节数组输入流对象后,对流进行读操作或者其他操作的方法有:
字节流方法
出流在内存中创建一个字节数组缓冲区,所有发送到输出流的数据保存在该字节数组缓冲区中。创建字节数组输出流对象有以下几种方式。
下面的构造方法创建一个32字节(默认大小)的缓冲区。

 OutputStream bOut = new ByteArrayOutputStream();

另一个构造方法创建一个大小为n字节的缓冲区。

OutputStream bOut = new ByteArrayOutputStream(int a)

成功创建字节数组输出流对象后,对流进行写或其他操作的方法有:
字节流方法
例子:

import java.io.*;public class ByteArrayStream {   public static void main(String args[])throws IOException {      ByteArrayOutputStream bOutput = new ByteArrayOutputStream(10);//申请一个20字节的流      while( bOutput.size()!= 10 ) {//boutput可以看成长度变化的字节缓冲区,尺寸随加入字节而变化。直到20 Byte         bOutput.write(System.in.read());//将用户输入的字节写入bOutput中      }      byte b [] = bOutput.toByteArray();      System.out.println("输出字节流中的内容:");      for(int x= 0 ; x < b.length; x++) {         System.out.print((char)b[x]);      }      System.out.printf("\n");      int c;      ByteArrayInputStream bInput = new ByteArrayInputStream(b);      System.out.println("将字节流中的字母转换为大写: " );         while(( c= bInput.read())!= -1) {            System.out.printf("%c",Character.toUpperCase((char)c));      }   }}

输出:
这里写图片描述

2.3. FilterInputStream和FilterOutputStream
它们是InputStream和OutputStream的子类,并没给出其它额外的功能实现,只是做了一层简单地封装。代表的有BufferedInputStream和BufferedOutputStream。DataInputStream和DataOutputStream
2.3.1 BufferedInputStream和BufferedOutputStream
BufferedInputStream如Buffer含义缓冲,意思是将InputStream第一次 read()足够的数据至内存缓冲区,后续调用read()时,先看看缓冲区是否有数据,如果有则从缓冲区读取,如果没有则从来源读取数据至缓冲区,这样可以减少直接读取数据的次数,从而提高效率。
同样BufferedOutputStream每次write()时可以将数据写入内存的缓冲区,缓冲区满了再将缓冲区的数据写入目的地,这样可以减少对目的地的写入次数。从而提高效率。
实例:

import java.io.*;public class BufferedIO {    public static void dump(InputStream src, OutputStream dest)                    throws IOException{           try(InputStream input=new BufferedInputStream(src);               OutputStream output =new BufferedOutputStream(dest)){                byte[] data=new byte[1024];                int length =-1;                while((length =input.read(data))!=-1){                    output.write(data,0,length);                }            }        }    }

2.3. 2 DataInputStream和DataOutputStream
DataInputStream 数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据
DataoutputStream 数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。他们可以用于操作基本数据类型的流对象。
实例:

import java.io.*;public class DataStream{   public static void main(String args[])throws IOException{      File directory = new File("source");       String path =directory.getCanonicalPath();      System.out.printf("当前路径: %s%n",path);      DataInputStream bInput = new DataInputStream(new                               FileInputStream(path+"/in.txt"));      DataOutputStream bOutput = new DataOutputStream(new                               FileOutputStream(path+"/out.txt"));      String ss;      while((ss = bInput.readLine()) != null){          String u = ss.toUpperCase();          System.out.println(u);          bOutput.writeBytes(u);      }      bInput.close();      bOutput.close();   }}

运行结果:
这里写图片描述
并且文件out.txt中已经被写入了in.txt的大写字母。
2.4. ObjectInputStream和ObjectOutputStream
如我们对Member 的number,name, age数据进行存储,读回时也是先取得number,name, age数据再用来创建Member实例。实际上如果使用ObjectInputStream和ObjectOutputStream可以将内存中的对象整个存储下来,之后再读入还原为对象。ObjectInputStream提供readObject()方法将数据读入为对象,ObjectOutputStream提供writeObject()方法将对象写至目的地。
实例:

import  java.io.*;public class Member implements Serializable {     private String number;    private String name;    private int age;    public Member(String number,String name,int age){        this.number=number;        this.name=name;        this.age=age;    }    @Override    public String toString() {        return String.format("(%s,%s,%d)",number,name,age);    }    public void save(){        try(ObjectOutputStream output=//建立DataOutputStream打包FileOutputStream            new ObjectOutputStream(new FileOutputStream(number))){                output.writeObject(this);//调用writeObject()方法写出对象            }catch(IOException ex){                throw new RuntimeException(ex);            }    }    public static Member load(String number){        Member member =null;        try(ObjectInputStream input=  //建立DataInputStream打包FileInputStream            new ObjectInputStream(new FileInputStream(number))){                member=(Member)input.readObject();//调用readObject()方法读入对象            }catch (IOException |ClassNotFoundException ex){                throw new RuntimeException(ex);            }            return member;    }}         
public class ObjectStream{    public static void main(String [] args){        Member[] members ={ new Member("B1234","Justin",90),                            new Member("C1234","Monica",80),                            new Member("D1234","Trene",75)};        for(Member member:members){            member.save();        }        System.out.println(Member.load("B1234"));        System.out.println(Member.load("C1234"));        System.out.println(Member.load("D1234"));    }}

运行结果如下图:
这里写图片描述

0 0
原创粉丝点击