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

  ------- <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:(字符输出流缓冲区对象写出文件)

 

public class BufferedWriterDemo {

    public static void main(String[] args) throws IOException {

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

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

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

       BufferedWriter bfw = new BufferedWriter(

              new FileWriter("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:(字符输出流缓冲区对象写出文件)

 

public class BufferedReaderDemo {

    public static void main(String[] args) throws IOException {

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

       // FileReader fr = 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

 */

public class CopyDirectory {

    public static void main(String[] args) {

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

    }

 

    /*

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

     */

    public static void 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流读写文件 传递参数,数据源,目的

     */

    public static void 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 = new byte[1024];

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

              fos.write(bytes, 0, len);

           }

       } catch (IOException ex) {

           throw new RuntimeException("复制失败");

       } finally {

           MyCloseStream.close(fis, fos);

       }

    }

}

 

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

 

public class TreeSetToText {

    public static void 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类:

public class Student {

    private String name;

    private int math;

    private int chinese;

    private int english;

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

       super();

       this.name = name;

       this.math = math;

       this.chinese = chinese;

       this.english = english;

    }

    public int total() {

       return math + chinese + english;

    }

 

    @Override

    public String toString() {

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

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

    }

}

//自定义比较器

public class StudentScoreComparator implements Comparator<Student>{

    public int 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功能

 

public class Test {

    public static void 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();

    }

}

public class TreeSetToText {

    public static void 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

 

    public static void 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

    public static void 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

 

    public static void 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

 

    public static void 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值