一、字节缓冲流

1、定义

缓冲区域:采用字节流输入或者输出数据时,用于存放读取或写出的数据,当缓冲区满时一次性输入或输出。

2、作用

提高输入或者输出的效率。输出时可使用手动输出flush()。
可读取或输出任何形式的数据如:文档,图片,音频,视频等。

3、读写步骤

(1)建立源文件路径file1或者目标文件路径file2;
(2)建立字节输入流FileInputStreaminput或FileOutputStream output;
(3)建立输入流缓冲区BufferedInputStreambufferInput或者输出流缓冲区BufferedOutputStream bufferOutput;有两个构造器,可设置缓冲区大小,默认为8192个字节。
(4)建立读取数据的字节数组或需输出的数据源(字符串或者字符数组等)byte[] bytes;
(5)通过缓冲区读取或者输出数据
buffernput.reader();
bufferOutput.writer();
(6)如果时输出数据,输出完毕需要刷新缓冲区:bufferOutput.flush();
(7)关闭流管道,关闭原则:先开的后关,后开的先关。
例题:

  1. public static void test1() {
  2. //创建File对象
  3. File file1 = new File("D:/JavaSE.zip");
  4. File file2 = new File("D:/new_JavaSE.zip");
  5. //创建输入输出流
  6. InputStream in = null;
  7. OutputStream out = null;
  8. //还需要缓冲流
  9. BufferedInputStream buffIn = null;
  10. BufferedOutputStream buffOut = null;
  11. try {
  12. in = new FileInputStream(file1);
  13. //创建缓冲输入流:缓冲区默认大小为8192字节,也可以手动设置缓冲区的大小
  14. buffIn = new BufferedInputStream(in, 8192);
  15. out = new FileOutputStream(file2);
  16. //创建缓冲输出流
  17. buffOut = new BufferedOutputStream(out,8*1024);
  18. //数据的读取操作还是和原来的一样
  19. //读取数据
  20. byte[] buff = new byte[128];
  21. int readLen = 0;
  22. //在读取数据之前获取当前时间
  23. long start = System.currentTimeMillis();//返回系统的当前时间
  24. //循环读取数据
  25. while((readLen = buffIn.read(buff))!=-1) {
  26. //将读取到的数据写出
  27. buffOut.write(buff, 0, readLen);//先写出到缓冲区,等缓冲区装满了之后再一并写出到目的地
  28. }
  29. //手动刷新:将缓冲区的数据强制刷新到目的地
  30. buffOut.flush();
  31. //数据写出完成之后再获取一下系统当前时间
  32. long end = System.currentTimeMillis();
  33. System.out.println("文件复制成功,耗时:"+(end-start)+"毫秒");//不到一秒
  34. } catch (FileNotFoundException e) {
  35. // TODO Auto-generated catch block
  36. e.printStackTrace();
  37. } catch (IOException e) {
  38. // TODO Auto-generated catch block
  39. e.printStackTrace();
  40. }finally {
  41. if(buffOut!=null) {
  42. try {
  43. buffOut.close();
  44. } catch (IOException e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. if(out!=null) {
  49. try {
  50. out.close();
  51. } catch (IOException e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. if(buffIn!=null) {
  56. try {
  57. buffIn.close();
  58. } catch (IOException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. if(in!=null) {
  63. try {
  64. in.close();
  65. } catch (IOException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. }
  70. }

二、字符缓冲流

1、定义

缓冲区域:采用字符流输入或者输出数据时,用于存放读取或写出的数据,当缓冲区满时一次性输入或输出。

2、作用

提高输入或者输出的效率。输出时可使用手动输出flush()。
只能用于输入或者输出文本文档。

3、读写步骤

(1)建立源文件路径file1或者目标文件路径file2;
(2)建立字符输入流FileInputStreamreader或FileOutputStream writer;
(3)建立输入流缓冲区BufferedReader bufferReader或者输出流缓冲区BufferedWritter bufferWritter;有两个构造器,可设置缓冲区大小,默认为8192个字节。
(4)建立读取数据的字符数组或需输出的数据源(字符串或者字符数组等)char[] ch;
(5)通过缓冲区读取或者输出数据
bufferReader.reade();
bufferWritter.write();
注意:1)读取时有新增方法:按行读取:String readLine();
2)每输出一行需要换行:newLine();
(6)如果时输出数据,输出完毕需要刷新缓冲区:bufferOutput.flush();
(7)关闭流管道,关闭原则:先开的后关,后开的先关。

public static void test1() {
        //创建数据源和目的地的File对象
        File file1 = new File("D:/File/bufferedReader.txt");
        File file2 = new File("D:/File/new_bufferedReader.txt");
        //创建字符缓冲流
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader(file1));//缓冲区 默认为8192字节
            bw = new BufferedWriter(new FileWriter(file2),20*1024);//缓冲区20kb
            //读取文件内容
            String buff = null;//缓冲读取的数据
            int readLen = 0;
            //通过循环读取数据
            while((buff = br.readLine())!=null) {//readLine()方法会一字符串的形式返回读取到的一行数组,如果数据为空,则返回null
                //处理数据
                System.out.println(buff);//打印下读取到的数据
                //写出数据到目的地
                bw.write(buff);
                //手动换行
                bw.newLine();
            }
            //刷新流
            bw.flush();
            System.out.println("文件复制成功");
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭流
            IOUtil.close(bw,br);
        }
    }

三、转换流

1、定义

将字节输入流转换为字符输入流;
将字节输出流转换为字符输出流。

2、作用

使用字符流输入或者输出数据时,使用默认的字符集,会产生乱码问题。使用转换流可避免这类问题。

3、读写步骤

(1)建立源文件路径file1或者目标文件路径file2;
(2)使用转换流建立字符输入流FileInputStreamreader或FileOutputStreamWritter writer;同时设置字符集;
reader = new InputStreamReader(file1,”输入字符集”);
writer = new OutputStreamWriter(file2,”输出字符集”);
(3)建立读取数据的字符数组或需输出的数据源(字符串或者字符数组等)char[] ch;
(4)通过转换流读取或者输出数据
reade.read();;
writer.write();
(5)如果时输出数据,输出完毕需要刷新缓冲区:writer.flush();
(6)关闭流管道,关闭原则:先开的后关,后开的先关。

public static void copyFile(File srcFile,File aimFile,String srcCharset,String aimCharset) {
        //创建字符转换输入流
        InputStreamReader inChange= null;
        //创建字符转换输出流
        OutputStreamWriter outChange = null;
        try {
            //字符转换输入流
            inChange = new InputStreamReader(new FileInputStream(srcFile), srcCharset);
            //字符转换输出流
            outChange = new OutputStreamWriter(new FileOutputStream(aimFile), aimCharset);
            //创建字符数组,用于读取数据
            char[] buffer = new char[512];
            //读取字符长度
            int readlen = 0;
            //循环读取数据
            while((readlen=inChange.read(buffer))!=-1) {
                //写出
                outChange.write(buffer);
                System.out.println(Arrays.toString(buffer));
            }
            //刷新管道
            outChange.flush();
            System.out.println("文件复制完成");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            OICloseUtil.close(outChange,inChange);
        }
    }

四、关闭流方法的封装

基本思路:
1、所有的流都共同实现接口closeable,所以可以通过closeable超类接收各种流。
2、因为流的数量不定,使用可变参数传入。

public static void close(Closeable ...objs){//参数:需要能够接收多个流对象
              //遍历objs,获取所有的流对象,然后关闭
              for(Closeable obj:objs) {
                     if(obj!=null){
                            //流对象不为null,则关闭流
                            try{
                                   obj.close();
                            }catch (IOException e) {
                                   //TODO Auto-generated catch block
                                   e.printStackTrace();
                            }
                     }
              }
       }

五、设计模式(单例模式)

单例模式分为饿汉模式和懒汉模式。其作用时用来确保该类运行时只存在该类的一个实例。

1、饿汉模式

基本思想:不管需不需要该类的实例,先创建一个该类的实例放着。需要用的时候可以直接用。
基本操作:将该类的属性和构造器均私有化并设置为静态属性,仅暴露一个方法,返回该类的仅有的这个实例。

class Singleton{
       //自己来创建一个实例:通过设置静态属性来创建该类的实例
       privatestatic Singleton instence = new Singleton();//类加载时就创建一个实例

       //私有化构造器:禁止外部创建该类的实例
       private Singleton() {};

       //获取创建的实例
       public static Singleton getInstance() {
              //返回创建好的实例
              return instence;
       }
}

2、懒汉模式

基本思想:先不创建实例,等外部需要时再创建该类的实例。
基本操作:将该类的属性和构造器均私有化并设置为静态属性,通过判断该类的实例是否存在,不存在时才创建。

class Singleton2{
       //定义静态属性
       privatestatic Singleton2 instance = null;//先不创建实例

       //私有化构造器
       privateSingleton2() {}

       //外部需要时,再通过方法阿里创建实例并返回
       publicstatic Singleton2 getInstance() {
              //先判断是否以及存在该实例
              if(instance== null) {
                     //创建实例
                     instance= new Singleton2();
              }
              returninstance;
       }
}