Java优化编程--核心类与性能 I/O流

      Java 的I/O流给我的感觉就是:要用到的时候用得很多,不用到的时候一点都不沾。Java 的I/O流作为最基本的输入输出系统,我想没多少人不会用到。然而许多人应该都只是使用其最方便的调用方式,而不会去加多一层缓冲。而其实加多一层缓冲区,只是一个很简单的工作却能使其性能有巨大的提高。
      Java的I/O类:
            基本输入/输出流:InputStream/OutputStream
            文件输入/输出流:FileInputStream/FileOutputStream
            对象输入/输出流:ObjectInputStream/ObjectOutputStream
            字符数据的输入/输出流:Reader/Writer
      在Java的一般输入/输出流中都是采用单字节的读取方法,每次只读取一个字节的数据,效率低。如果在读取与写入时增加一个临时缓冲区,每次便可读取一个缓冲区大小的数据块,提高效率。
mark--1:系统缓冲流提高性能
      ......//方式一
      InputStream in = null;
      OutputStream out = null;
      try{
            in = new FileInputStream( "D:/fileFrom.err" ); 
            out = new FileOutputStream( "D:/fileTo.err" );
            while( true ){
                  int bytedata = in.read();
                  if( bytedata == 1 )
                        break;
                  out.write(bytedata );
            }
      }finally{......}
      ......//方式二
      InputStream inBuffer = null;
      OutputStream outBuffer = null;
      try{
            InputStream in = new FileInputStream( "D:/fileFrom.err" ); 
            inBuffer = new BufferedInputSteam(in);                              //系统缓冲
            OutputStream out = new FileOutputStream( "D:/fileTo.err" );
            inBuffer = new BufferedInputSteam(out);                              //系统缓冲
            while( true ){
                  int bytedata = in.read();
                  if( bytedata == 1 )
                        break;
                  out.write(bytedata );
            }
      }finally{......}
      文件763KB下:
      方式一是直接读取与写入的,耗时:4844ms
      方式二是系统缓冲区类读取与写入,耗时:3156ms

mark--2:自定义缓冲区提高I/O操作效率
      自定义缓冲区其实就是自己创建一个数组来担当缓冲区的角色。
      
      在利用数组做缓冲区之前先了解下数组读取与写入的方法与单字节的区别:
      单字节读取与写入:
      FileInputStream.read();
      FileOutputStream.write( int b );
      数组读取与写入:
      InputStream.read(byte[] b);
      InputStream.read(byte[] b, int off, int length );
      FileOutputStream.write(byte[] b );
      FileOutputStream.write(byte[] b, int off, int length );
      除此之外系统缓冲区类也有同样的方法:(也就是将参数改成和上面的一样)
      BufferInputStream.read(byte[] b, int off, int length );
      BufferOutputSteam.write(byte[] b, int off, int length );

      现在使用自定义数组来作缓冲区,看看时间效率如何。
       ......
      InputStream in = null;
      OutputStream out = null;
      try{
            in = new FileInputStream( "D:/fileFrom.err" ); 
            out = new FileOutputStream( "D:/fileTo.err" );
            int availableLength = in.avialable();
            byte[] totalBytes = new byte[availableLength ];
            int bytedata = in.read(totalBytes);
            out.write(totalBytes);
      }finally{......}
      同mark--1同样的文件,此时耗时109ms。此时需要注意的就是,由于此时的缓冲区是自定义的,大少也由你来决定。这便要你选择恰当大小的缓冲区,不然如果你的缓冲区过大,而运行的PC的内存又太小的话,可想而知这必将影响系统速度。另外如果文件很小而选取一个很大的缓冲区也将会造成浪费。

mark--3:字符输入/输出流类的缓冲区
      ......//方式一
      Reader reader = new FileReader( "D:/filefrom.err" );
      int c = 0;
      while( (c = reader.read() ) != -1 ){}
      ......//方式二,使用缓冲区
      reader = new FileReader( "D:/filefrom.err" );
      reader = new BufferedReader( reader );
      ......
      运行效率比较: 方式一:361ms  方式二:26ms

mark--4:压缩文件拷贝性能的提高--压缩流
      压缩流位置:
      java.util.Zip.ZipInputStream
      java.util.Zip.ZipOutputStream
      
      ......
      ZipOutPutStream zipoutputstream = new ZipOutPutStream ( new java.io.FileOutputStream( "D:/fileto.err" ) );     
      zipoutputstream.setMethod( ZipOutPutStream.DEFLATED );
      File file = new File( "D:/filefrom.err" );
      byte[] rgb = new byte[1000];
      int n;
      //创建一个ZIP entry
      ZipEntry zipentry = new ZipEntry( "D:/fileto.err" );
      //添加ZIP entry 与相关数据
      zipoutputsteam.putNextEntry( zipentry );
      FileInputStream fileInputstream = new FileInputStream( file );
      while( (n = fileInputstream.read(rgb) ) > -1 ){
            zipoutputstream.write(rgb, 0, n);
      }
      ......
      与直接通过文件输入输出流读写文件相比,压缩流耗时78ms,直接读写耗时172ms。
      
      


      




posted @ 2009-09-27 20:37  怀想  阅读(959)  评论(1编辑  收藏  举报