JAVA基础复习与总结<八> 缓冲流_数据流_对象流_IO总结

时间:2022-05-18 15:22:38

缓冲流、数据流以及对象流

一、缓冲流

缓冲流的概念:在读写的时候,对于单字节的读取会造成硬盘的频繁读写,增加访问次数,降低了读取文件的效率。而引入缓冲流之后,就可以将多个字节写入缓冲区,在缓冲区积累之后再输入输出。

注意:缓冲流属于包装流,只能对已有的流进行封装,不能直接关联文件进行操作。

1.1 字节缓冲流

字节缓冲输入/输出流:BufferedInputStream/BufferedOutputStream

1)继承自FilterInputStream/FilterOutputStream类

2)FilterInputStream/FilterOutputStream继承于InputStream/OutputStream抽象基类

3)BufferedInputStream/BufferedOutputStream的作用就是为了“输入/输出字节流提供缓冲功能”

4)缓冲输入流每次读入和写出操作都是对缓冲区域执行的,而不是直接操作硬盘文件

1.1.1 字节缓冲输入流构造方法

BufferedInputStream(InputStream in)

创建一个BufferedInputStream并保存其参数,即输入流in,以便将来使用。

BufferedInputStream(InputStream in, int size)

创建具有指定缓冲区大小的BufferedInputStream并保存其参数,即输入流in,以便将来使用。

1.1.2 字节缓冲输出流构造方法

BufferedOutputStream(OutputStream out)

创建一个新的缓冲输出流,以将数据写入指定的底层输出流。

BufferedOutputStream(OutputStream out, int size)

创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。

1.2 字符缓冲流

字符缓冲输入/输出流:BufferedReader/BufferedWriter

1)继承自Reader/Writer抽象基类

2)BufferedReader/BufferedWriter的作用就是为“输入/输出字符流提供缓冲功能”。

3)BufferedReader/BufferedWriter没有声明自己任何新的方法,他只是覆盖了基类方法。

1.2.1 字符缓冲输入流构造方法

BufferedReader(Reader in )

创建一个使用默认大小输入缓冲区的缓冲字符输入流。

BufferedReader(Reader in, int size)

创建一个使用指定大小输入缓冲区的缓冲字符输入流。

1.2.2 字符缓冲输出流构造方法

BufferedWriter(Writer out )

创建一个使用默认大小输出缓冲区的缓冲字符输出流。

BufferedWriter(Writer out, int size)

创建一个使用指定大小输出缓冲区的缓冲字符输出流。

1.3 缓冲流程序举例

/**

* 字节流文件拷贝+缓冲流,提高性能

* 在节点流外面包一层缓冲流

* 缓冲流(节点流)

*/

public class DemoBuffered01 {

public static void main(String[] args ){

String src = "/Users/kk";

String dest = "/Users/kk/Desktop/22 .txt";

copyFile(src,dest);

}

/**

         * 文件的拷贝

         * param源文件路径

         *      目标文件路径

         */

        public static void copyFile(String srcPath ,String destPath){

//1、建立联系  在copy过程中确保源文件存在且为文件。 目的地文件可以不存在

File src = new File(srcPath);

File dest = new File(destPath);

copyFile(src,dest);

}

/**

         * 文件的拷贝

         * param源文件File

         *      目标文件File

         */

        public static void copyFile(File src,File dest){   //方法重载

//1、建立联系  在copy过程中确保源文件存在且为文件。 目的地文件可以不存在

if(!src.isFile()){ //不是文件或为null

System.out.println(“不能拷贝文件");

return;

}

//2、选择流

InputStream is =null;

OutputStream os =null;

try {

is = new BufferedInputStream(new FileInputStream(src));

os = new BufferedOutputStream(new FileOutputStream(dest));

} catch (FileNotFoundException e) {

e.printStackTrace();

System.out.println("文件不存在");

}

//3、文件的拷贝  读取和写出的循环

byte[] flush = new byte[1024];

int len = 0;

try {

//读取

while ( (len=is.read(flush))!=-1){

//写出

os.write(flush,0,len);

}

os.flush(); //强制刷出

}

catch (IOException e) {

e.printStackTrace();

System.out.println("拷贝失败");

}finally {

try {

//4、释放资源

if(is!=null)is.close();

if(os!=null)os.close();

} catch (IOException e) {

e.printStackTrace();

System.out.println("关闭失败");

}

}

}

}

二、数据流

2.1 数据输入输出流概念

1)文件流和缓冲流仅仅支持简单的字节写入写出,支持的读入写出方法局限性比较大。

2)数据流允许应用程序以适当方式将数据以Java基本数据类型写入和读出文件。

3)数据流提供了比文件流和缓冲流更加丰富的读入写出操作

4)由于数据类底层依然是字节操作,所以数据流为字节流类型的扩展包装流

2.2 数据流继承体系 

JAVA基础复习与总结<八> 缓冲流_数据流_对象流_IO总结

2.2.1 数据输入流构造方法

DataInputStream(InputStream in)

使用指定的底层InputStream创建一个DataInputStream。

2.2.2 数据输出流构造方法

DataOutputStream(OutputStream out)

创建一个新的数据输出流,将数据写入指定基础输出流。

2.3、数据流的读写方法 

3、对象流

3.1 对象流概念

1)所谓对象流就是将对象进行流化后通过流传输,我们可以直接将流化后的对象进行文件读写操作。

2)对象流化就是将Java对象转化为字节序列。

3)需要进行对象流传输的对象所关联的类必须序列化。

3.2 序列化

1)需要序列化的类必须实现Serializable接口

2)Serializable接口没有抽象方法,只是标注该对象可以被序列化

3)没有实现Serializabke接口类的对象是不能通过对象流传输的

3.3 对象输入流:ObjectInputStream

ObjectInputStream()

为了完全重新实现ObjectInputStream的子类提供的一种方式,让它不必分配仅由ObjectInputStream的实现使用的私有数据。

ObjectInputStream(InputStream in)

创建从指定InputStream读取的ObjecrInputStram。

3.4 对象输出流:ObjectOutputStream

ObjectOutputStream()

为了完全重新实现ObjectOutputStream的子类提供的一种方式,让它不必分配仅由ObjectOutputStream的实现使用的私有数据。

ObjectOutputStream(OutputStream out)

创建从指定OutputStream读取的ObjecrOutputStram。

3.5 对象流的基本操作

对象输出流(ObjectOutputStream): writeObject(Object obj)方法可以对参数指定的obj对象进行序列化成字节,并把得到的字节写到输出流关联的终端(可以是文件或者网络的URI)。

对象输入流(ObjectInputStream): readObject()方法可以从一个终端(可以是文件或者网络的URI)读取一个字节序列,再对当前字节序列进行反序列化为一个对象,并将当前对象返回。

3.6 对象流应用实例

/**

* 不是所有的对象都可以序列化  要声明接口java.io.Serializable

* 不是所有的属性都需要序列化  对于transient声明后就不能序列化

*/

public class ObjectDemo01  {

    public static void main(String[] args){

        ser1("/Users/qianjiapeng/Desktop/12.txt");

        read("/Users/qianjiapeng/Desktop/12.txt");

    }

    //反序列化,把文件内存储的对象输出出来

    public static void read (String destPath){

        //创建源

        File src = new File(destPath);

        //选择流

        ObjectInputStream dis =null;

        try {

            dis = new ObjectInputStream(

                    new BufferedInputStream(

                            new FileInputStream(src)));

            Object

                obj = dis.readObject();

            if(obj instanceof  ObjectEmployee){

                ObjectEmployee emp  = (ObjectEmployee)obj;

                System.out.println(emp.getName()) //这句会输出null,因为我们定义nametransient

                System.out.println(emp.getSalary());

                obj= dis.readObject();

                int[] arr =(int []) obj;

                System.out.println(Arrays.toString(arr));

        }

         }catch (FileNotFoundException e){

            e.printStackTrace();

        }catch (IOException e){

            e.printStackTrace();

        }catch (ClassNotFoundException e){

            e.printStackTrace();

        }finally {

            try {

                dis.close();

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

    }

   

        //序列化,把对象数组输出到文件

    public static void ser1(String destPath){

        ObjectEmployee emp = new ObjectEmployee("Dream Job",1000000);

        int[] arr = {1,2,3,4,5,6};

        File dest = new File(destPath);

        //选择流DataOutputStream

        ObjectOutputStream dos = null;

        try {

            dos = new ObjectOutputStream(

                    new BufferedOutputStream(

                            (new FileOutputStream(dest))));

        } catch (IOException e) {

            e.printStackTrace();

        }

        //操作要注意写出的顺序,写出的顺序是为读取作准备的

        //不一致时,读取可能会出现问题

        try {

            dos.writeObject(emp);

            dos.writeObject(arr);

            //释放资源

            dos.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}

四、IO流总结

JAVA基础复习与总结<八> 缓冲流_数据流_对象流_IO总结