Java IO进阶

引言: 对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统是一项艰难的任务 《Thinking in Java 》

概述: Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。java.io 包中的流支持很多种格式,比如:基本类型、对象、本地化字符集等等。一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据。Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。

        Java 的 I/O 操作类在包 java.io 下,大概有将近 80 个类,但是这些类大概可以分成四组,分别是:

  1. 基于字节操作的 I/O 接口:InputStream 和 OutputStream
  2. 基于字符操作的 I/O 接口:Writer 和 Reader
  3. 基于磁盘操作的 I/O 接口:File
  4. 基于网络操作的 I/O 接口:Socket
  5. 新的输入/输出:NIO

       本文不赘述IO的基本使用,主要记录性能测试结果和分析IO中的设计模式

       一:性能测试

            1.不使用缓冲流,使用FileInputStream和FileoutputStream拷贝文件

public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            long begin = System.currentTimeMillis();
            //测试文件150MB
            fileInputStream = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\深入了解计算机系统.pdf"));
            fileOutputStream = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\bb.pdf"));
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = fileInputStream.read(bytes)) != -1) {
                fileOutputStream.write(bytes, 0, len);
            }
            System.out.println("耗时:"+(System.currentTimeMillis()-begin));//耗时:1747
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != fileInputStream) {
                fileInputStream.close();
            }
            if (null != fileOutputStream) {
                fileOutputStream.close();
            }
        }
    }

         

          2.不使用输入缓冲流,使用FileInputStream和FileoutputStream,BufferedOutputStream拷贝文件

 public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        BufferedOutputStream out = null;
        try {
            long begin = System.currentTimeMillis();
            //测试文件150MB
            fileInputStream = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\深入了解计算机系统.pdf"));
            fileOutputStream = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\bb.pdf"));
            out = new BufferedOutputStream(fileOutputStream);
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = fileInputStream.read(bytes)) != -1) {
                out.write(bytes, 0, len);
            }
            System.out.println("耗时:"+(System.currentTimeMillis()-begin));//耗时:723
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != fileInputStream) {
                fileInputStream.close();
            }
            if (null != out) {
                out.close();
            }
            if (null != fileOutputStream) {
                fileOutputStream.close();
            }
        }
    }

 

            3.不使用输出缓冲流,使用FileInputStream,BufferedInputStream和FileoutputStream拷贝文件

public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = null;
        BufferedInputStream in = null;
        FileOutputStream fileOutputStream = null;
        try {
            long begin = System.currentTimeMillis();
            //测试文件150MB
            fileInputStream = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\深入了解计算机系统.pdf"));
            in = new BufferedInputStream(fileInputStream);
            fileOutputStream = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\bb.pdf"));
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = in.read(bytes)) != -1) {
                fileOutputStream.write(bytes, 0, len);
            }
            System.out.println("耗时:"+(System.currentTimeMillis()-begin));//耗时:1085
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != in) {
                in.close();
            }
            if (null != fileInputStream) {
                fileInputStream.close();
            }
            if (null != fileOutputStream) {
                fileOutputStream.close();
            }
        }
    }

           

         4.全部使用缓冲流,使用FileInputStream,BufferedInputStream和FileoutputStream,BufferedOutputStream拷贝文件

public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = null;
        BufferedInputStream in = null;
        FileOutputStream fileOutputStream = null;
        BufferedOutputStream out = null;
        try {
            long begin = System.currentTimeMillis();
            //测试文件150MB
            fileInputStream = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\深入了解计算机系统.pdf"));
            in = new BufferedInputStream(fileInputStream);
            fileOutputStream = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\bb.pdf"));
            out = new BufferedOutputStream(fileOutputStream);
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = in.read(bytes)) != -1) {
                out.write(bytes, 0, len);
            }
            System.out.println("耗时:"+(System.currentTimeMillis()-begin));//耗时:483
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != in) {
                in.close();
            }
            if (null != fileInputStream) {
                fileInputStream.close();
            }
            if (null != out) {
                out.close();
            }
            if (null != fileOutputStream) {
                fileOutputStream.close();
            }
        }
    } 

         为什么使用Buffer后,速度得到了明显,其实道理也很简单,避免的多次IO造成的资源消耗,将数据拷贝到内存缓冲区,直接从内存缓存区取数据,看看BufferedInputStream的源码就一目了然。

 

         二:IO中用到的设计模式

              在java语言 I/O库的设计中,使用了两个结构模式,即 装饰模式 和 适配器模式 。

  FileInputStream fileInputStream = new FileInputStream(new File(""));
        fileInputStream.read();
        //适配器模式  FileInputStream是字节流,而并没有字符流读取字符的一些api,因此通过InputStreamReader将其转为Reader子类,因此有了可以操作文本的文件方法。
        //换句话说,就是将FileInputStream读取一个字节流的方法扩展转换为InputStreamReader读取一个字符流的功能
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
        inputStreamReader.read();
        //装饰器模式  构造了缓冲字符流,将FileInputStream字节流包装为BufferedReader过程就是装饰的过程,刚开始的字节流FileInputStream只有read一个字节的方法,
        //包装为inputStreamReader后,就有了读取一个字符的功能,在包装为BufferedReader后,就拥有了read一行字符的功能。
        BufferedReader reader = new BufferedReader(inputStreamReader);
        reader.read();

 

                

        附录 常用的IO相关工具类,当然公司一般也会自己封装

          

 

  

 
posted @ 2019-08-09 10:49  Don'tYouSee  阅读(300)  评论(0)    收藏  举报