黑马程序员——第十三篇:字符缓冲流、IO流练习、其他流对象

来源:互联网 发布:淘宝美工教程视频 编辑:程序博客网 时间:2024/06/08 16:57

  ------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a

  href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

1.字符流缓冲区对象

缓冲区,出现目的,提高原有流对象的操作效率

 

1. BufferedWriter 字符输出流缓冲区对象

BufferedWriter继承Writer,方法写的方法

write,单个字符,字符数组,字符数组一部分,字符串

 

构造方法:写就数据目的

BufferedWriter(Writer out)可以传递任意的字符输出流

       所有的字符输出流,都是Writer类子类,子类对象

Writer子类对象 FileWriter OutputStreamWriter

 

自己独特的方法:

void newLine()写入换行,跨平台

 

程序Demo:(字符输出流缓冲区对象写出文件)

 

publicclass BufferedWriterDemo {

   publicstaticvoid main(String[] args)throws IOException {

      //创建字符输出流,便捷类

      // FileWriterfw = new FileWriter("c:\\buffer.txt");

      //创建字符输出流缓冲区对象,传递字符输出流

      BufferedWriter bfw = new BufferedWriter(

             newFileWriter("c:\\buffer.txt"));

      //写字符串

      bfw.write("abc");

      bfw.flush();

      //使用缓冲区方法newLine换行

      bfw.newLine();

      bfw.write("hello");

      bfw.flush();

      System.out.println();

      bfw.close();

   }

}

 

2. BufferedReader 字符输入流缓冲区对象

   BufferedReader 继承Reader方法读取

   read() 单个字符,字符数组

   缓冲区可以读取文本中的行

 

   构造方法:写的就是读取数据源

   BufferedReader(Reader r) 可以传递任意的字符输出流

   传递Reader类的子类对象, FileReader InputStreamReader

 

   读取方法,读取文本一行

String readLine() 每个文本中,行结束,换行符

 

 程序Demo:(字符输出流缓冲区对象写出文件)

 

publicclass BufferedReaderDemo {

   publicstaticvoid main(String[] args)throws IOException {

      //创建字符输入流对象,封装文件

      // FileReaderfr = new FileReader("c:\\buffer.txt");

      //创建字符输入流缓冲区对象,传递字符输入流

      BufferedReader bfr = new BufferedReader(

             new FileReader("c:\\buffer.txt"));

      //使用BufferedReader类方法readLine读取文本行,返回String

      //利用循环读取,条件是readLine()返回值不是null

      String line = null;

      while ((line = bfr.readLine()) !=null) {

          System.out.println(line);

      }

 

      bfr.close();

   }

}

2. IO流对象总结

  OutputStream 字节输出

    FileOutputStream

    BufferedOutputStream

 

    InputStream 字节输入流

    FileInputStream

    BufferedInputStream

 

    Writer 字符输出流

    OutputStreamWriter

    FileWriter

    BufferedWriter

 

    Reader 字符输入流

    InputStreamReader

    FileReader

    BufferedReader

  

  使用IO流对象小规律

  需要进行数据传输,必须创建IO对象

 

  A:明确数据源:输入

    文本类型:

    字符输入流,读取文本文件

         需要高效吗,如果需要字符数组缓冲

         需要单独操作文本行,使用缓冲区

         需要操作编码表,转换流

 

    非文本类型:

    字节输入流,读取文件

         需要高效吗,如果需要字节数组,或者缓冲区流

 

    类型无法明确

    字节输入流,读取文件

         需要高效吗,如果需要字节数组,或者缓冲区流

 

  B:明确数据目的:输出

    文本类型:

    字符输出流,写文本文件

         需要高效吗,如果需要字符数组缓冲

         需要单独操作文本行,使用缓冲区

         需要操作编码表,转换流

 

    非文本类型:

    字节输出流,写文件

         需要高效吗,如果需要字节数组,或者缓冲区流

 

    类型无法明确:

    字节输入流,读取文件

         需要高效吗,如果需要字节数组,或者缓冲区流

 

技巧:如果要求只是复制文件,完全选用字节流实现

3IO流综合案例:

   1:复制文件夹(里面有多个文件),复制完后将所有文件后缀名改为.java

/*

 *案例,复制目录,文件夹,没有使用递归,只能复制1个文件夹

 *数据源: c:\\demo

 *数据目的:d:\\

 *流对象实现文件读写,不能操作文件夹,File

 *  实现步骤:

 *    数据目的端,创建一个和数据源同名文件夹 OK

 *    获取数据源目录下的文件

 *    获取数据源文件名

 *    和数据目的文件夹组合File对象

 *    IO流读写字节数组

 *    

 * 复制成功================================

 * 

 * 被复制后的数据目的:所有的文件名的后缀修改成 .java

 * File类方法 renameTo

 */

publicclass CopyDirectory {

   publicstaticvoid main(String[] args) {

      copyDir(new File("c:\\demo"),new File("d:\\"));

   }

 

   /*

    * 定义方法,实现文件夹复制 有参数,数据源,目的

    */

   publicstaticvoid copyDir(File src, File target) {

      //数据目的端,创建一个和数据源同名文件夹

      //取得数据源文件夹名字 File类方法getName()

      String srcDirName = src.getName();// demo

      //创建文件夹 target d:\\ srcDirName demo

      //创建File对象,File父路径,String子路径

      File targetDirName = new File(target, srcDirName);

      //使用创建目录方法 mkdirs()

      targetDirName.mkdirs();// d:\demo

      //获取数据源目录下的全部文件

      // File类方法listFiles()

      File[] srcFileNames = src.listFiles();

      for (File srcFileName : srcFileNames) {

          //遍历所有文件的过程中,获取数据源的文件名

          String filename = srcFileName.getName();

          //将目的文件夹名targetDirName和数据源文件名组成File对象

          // File构造,File父路径,String子路径

          File targetFileName = new File(targetDirName, filename);

          //调用复制文件的方法,传递数据源和数据目的

          copyFile(srcFileName, targetFileName);

      }

      //进行文件名的修改

      //获取数据目的文件夹里所有文件名

      File[] targetFileNames = targetDirName.listFiles();

      for (File targetFileName : targetFileNames) {

          //使用文件名对象targetFileName调用方法renameTo修改

          // targetFileName d:\demo\1.txt变成 d:\demo\1.java

          //获取数据目的文件名

          String name = targetFileName.getName();

          // String类方法,反向索引,查询.最后一次出现索引

          int index = name.lastIndexOf('.');

 

          //截取字符串,新的文件名已经OK

          name = name.substring(0, index) + ".java";

          //将数据目的文件夹targetDirName和新的文件名组合成File

          File reNameFile = new File(targetDirName, name);

          //遍历到的目的中的文件对象,调用方法renameTo

          targetFileName.renameTo(reNameFile);

 

      }

   }

 

   /*

    * 定义方法,IO流读写文件 传递参数,数据源,目的

    */

   publicstaticvoid copyFile(File src, File target) {

      //创建2个字节流对象

      FileInputStream fis = null;

      FileOutputStream fos = null;

      try {

          //创建流对象,数据源和目的都是File类型

          fis = new FileInputStream(src);

          fos = new FileOutputStream(target);

          int len = 0;

          byte[] bytes =newbyte[1024];

          while ((len = fis.read(bytes)) != -1) {

             fos.write(bytes, 0, len);

          }

      } catch (IOException ex) {

          thrownew RuntimeException("复制失败");

      } finally {

          MyCloseStream.close(fis, fos);

      }

   }

}

 

2、键盘输入5名同学的信息(姓名、数学、语文、英语),按总分由高到低的顺序排序,并将排序的结果存到文本中。

 

publicclass TreeSetToText {

   publicstaticvoid main(String[] args)throws IOException {

      //创建键盘输入对象

      Scanner sc = new Scanner(System.in);

      //创建集合对象TreeSet,存储Student对象

      Set<Student> set = new TreeSet<Student>(new StudentScoreComparator());

      //键盘接收5个学生对象信息

      for (int x = 0; x < 5; x++) {

          String s = sc.nextLine();

          //按照空格,对字符串切割

          String[] str = s.split(" +");

          //创建学生对象,存储集合

          set.add(new Student(str[0], Integer.parseInt(str[1]), Integer.parseInt(str[2]), Integer.parseInt(str[3])));

      }

      //创建流对象,写学生的信息,每个学生占一行

      BufferedWriter bfw = new BufferedWriter(new FileWriter(

             "c:\\student.txt"));

      //遍历TreeSet集合,获取出存储的学生对象,存储到文本中

      for (Student s : set) {

          //写进去,是学生的对象toString方法即可

          bfw.write(s.toString());

          bfw.newLine();

          bfw.flush();

      }

      bfw.close();

   }

}

引用的student类:

publicclass Student {

   private Stringname;

   privateintmath;

   privateintchinese;

   privateintenglish;

   public Student(String name,int math,int chinese,int english) {

      super();

      this.name = name;

      this.math = math;

      this.chinese = chinese;

      this.english = english;

   }

   publicint total() {

      returnmath +chinese +english;

   }

 

   @Override

   public String toString() {

      return"Student [name=" +name +", math=" +math +", chinese="

             + chinese +", english=" +english +"]";

   }

}

//自定义比较器

publicclass StudentScoreComparatorimplements Comparator<Student>{

   publicint compare(Student s2,Student s1){

      int total1 = s1.total();

      int total2 = s2.total();

      int total = total1-total2;

      return total==0?s1.getName().compareTo(s2.getName()):total;

   }

}

3.装饰设计模式

1、设计模式:使用程序,解决实际生活中的存在问题

  解决的思想,设计模式(OOP Oriented  Object  Programming)

 

  装饰设计模式:设计思想,增强原有对象的功能

 

  已经设计好了一个类,创建类对象,调用类中的方法

  日后发现,类的功能不够,不够强大,不能修改源代码

 

  出现装饰设计思想,解决这个问题

 

  Reader类读取流,FileReader读取文件

  字符,数组,能读取行吗

 

  开发 BufferedReader,出现后,可以实现读取行的功能

  FileReader原始对象,BufferedReader原始对象的装饰类

2、程序Demo:自定义readLine功能

 

publicclass Test {

   publicstaticvoid main(String[] args)throws IOException {

      //创建FileReader对象,传递文件

      FileReader fr = new FileReader("d:\\1.txt");

      //创建自定义的缓冲区对象,传递字符输入流

      MyReadLine my = new MyReadLine(fr);

      String line = null;

      while ((line = my.readLine()) !=null) {

          System.out.println(line);

      }

      my.close();

   }

}

publicclass TreeSetToText {

   publicstaticvoid main(String[] args)throws IOException {

      //创建键盘输入对象

      Scanner sc = new Scanner(System.in);

      //创建集合对象TreeSet,存储Student对象

      Set<Student> set = new TreeSet<Student>(new StudentScoreComparator());

      //键盘接收5个学生对象信息

      for (int x = 0; x < 5; x++) {

          String s = sc.nextLine();

          //按照空格,对字符串切割

          String[] str = s.split(" +");

          //创建学生对象,存储集合

          set.add(new Student(str[0], Integer.parseInt(str[1]), Integer.parseInt(str[2]), Integer.parseInt(str[3])));

      }

      //创建流对象,写学生的信息,每个学生占一行

      BufferedWriter bfw = new BufferedWriter(new FileWriter(

             "c:\\student.txt"));

      //遍历TreeSet集合,获取出存储的学生对象,存储到文本中

      for (Student s : set) {

          //写进去,是学生的对象toString方法即可

          bfw.write(s.toString());

          bfw.newLine();

          bfw.flush();

      }

      bfw.close();

   }

}

 

4.基本数据类型流对象

 专门用于操作Java中的基本数据类型

 

 1. DataOutputStream 写基本类型

   继承OutputStream,标准的字节输出流

 

   构造方法:

     DataOutputStream(OutputStream out)

     传递任意字节输出流,FileOutputStream

 

     new DataOutputStream(new FileOutputStream(""))

 

     void writeInt(int n)将基本类型int,写到输出流,4字节

程序Demo

 

   publicstaticvoid method()throws IOException{

      //创建字节输出流,封装文件

      FileOutputStream fos = new FileOutputStream("d:\\data.txt");

      //创建基本数据类型输出流,传递字节输出流

      DataOutputStream dos = new DataOutputStream(fos);

      //写基本类型int

      dos.writeInt(97);

      //写基本类型boolean

      dos.writeBoolean(false);

      //写基本类型double

      dos.writeDouble(5.6);

      dos.writeInt(-1);

      dos.close();

   }

 

 2. DataInputStream 读取基本类型

    继承InputStream.标准的字节输入流

 

    构造方法:

      DataInputStream(InputStream in)

      传递任意字节输入流,FileInputStream

 

      new DataInputStream(new FileInputStream(""))

 

      int readInt()读取Java基本类型int,与机器无关

程序Demo

   publicstaticvoid method_1()throws IOException{

      //创建字节输入流,封装文件

      FileInputStream fis = new FileInputStream("c:\\data.txt");

      //创建读取基本数据类型流对象,传递字节输入流

      DataInputStream dis = new DataInputStream(fis);

      //读取基本类型int

      int x = dis.readInt();

      System.out.println(x);

      //读取布尔类型

      boolean b = dis.readBoolean();

      System.out.println(b);

      //读取double类型

      double d = dis.readDouble();

      System.out.println(d);

      //读取int类型

      x = dis.readInt();

      System.out.println(x);

      

      x = dis.readInt();

      System.out.println(x);

      

      dis.close();

   }

 

5. Properties集合IO关联使用

 存储键值对的集合,键唯一性

 

 IO读取文件,将文件中的键值对,存储到集合

 

 1. Properties方法load

  load方法,传递字节,或者字符输入流

  作用:从流中提取键值对,存储集合

   程序Demo

 

   publicstaticvoid method()throws IOException{

      //创建集合对象

      Properties pro = new Properties();

      //创建字节输入流

      FileInputStream fis = new FileInputStream("c:\\pro.txt");

      //集合方法load,传递字节输入流

      pro.load(fis);

      fis.close();

      System.out.println(pro);

   }

 

 2. Properties方法store

  store方法,传递字节,或者字符输出流

  作用:集合中键值对,写回文件中

   程序Demo

 

   publicstaticvoid method_1()throws IOException{

      //创建集合对象

      Properties pro = new Properties();

      //创建字节输入流

      FileInputStream fis = new FileInputStream("c:\\pro.txt");

      //集合方法load,传递字节输入流

      pro.load(fis);

      fis.close();

      System.out.println(pro);

      //修改集合键值对,键是age,值修改成30

      pro.setProperty("age","30");

      System.out.println(pro);

      //创建字节输出流

      FileOutputStream fos = new FileOutputStream("c:\\pro.txt");

      //集合方法store传递字节输出流

      pro.store(fos, "");

      fos.close();

   }




 

0 0
原创粉丝点击