您的位置:首页 > 编程语言 > Java开发

Java-进阶-day10-IO流_03

2020-01-12 13:23 197 查看

Java进阶-day08-IO流_01

今日内容

  • IO流案例
  • 标准流
  • 打印流
  • 对象流
  • Properties

一. IO流案例

  • 集合到文件数据排序改进版
  • 案例需求 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)。要求按照成绩总分从高到低写入文本文件
  • 格式:姓名,语文成绩,数学成绩,英语成绩 举例:林青霞,98,99,100
  • 分析步骤
      定义学生类
    1. 创建TreeSet集合,通过比较器排序进行排序
    2. 键盘录入学生数据
    3. 创建学生对象,把键盘录入的数据对应赋值给学生对象的成员变量
    4. 把学生对象添加到TreeSet集合
    5. 创建字符缓冲输出流对象
    6. 遍历集合,得到每一个学生对象
    7. 把学生对象的数据拼接成指定格式的字符串
    8. 调用字符缓冲输出流对象的方法写数据
    9. 释放资源
    public class TreeSetToFileDemo {
    public static void main(String[] args) throws IOException {
    //创建TreeSet集合,通过比较器排序进行排序
    TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
    @Override
    public int compare(Student s1, Student s2) {
    //成绩总分从高到低
    int num = s2.getSum() - s1.getSum();
    //次要条件
    int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
    int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;
    int num4 = num3 == 0 ? s1.getName().compareTo(s2.getName()) : num3;
    return num4;
    }
    });
    
    //键盘录入学生数据
    for (int i = 0; i < 5; i++) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请录入第" + (i + 1) + "个学生信息:");
    System.out.println("姓名:");
    String name = sc.nextLine();
    System.out.println("语文成绩:");
    int chinese = sc.nextInt();
    System.out.println("数学成绩:");
    int math = sc.nextInt();
    System.out.println("英语成绩:");
    int english = sc.nextInt();
    
    //创建学生对象,把键盘录入的数据对应赋值给学生对象的成员变量
    Student s = new Student(name,chinese,math,english);
    // s.setName(name);
    // s.setChinese(chinese);
    // s.setMath(math);
    // s.setEnglish(english);
    
    //把学生对象添加到TreeSet集合
    ts.add(s);
    }
    
    //创建字符缓冲输出流对象
    BufferedWriter bw = new BufferedWriter(new FileWriter("day10_code\\ts.txt"));
    
    //遍历集合,得到每一个学生对象
    for (Student s : ts) {
    //把学生对象的数据拼接成指定格式的字符串
    //格式:姓名,语文成绩,数学成绩,英语成绩
    StringBuilder sb = new StringBuilder();
    sb.append(s.getName()).append(",").append(s.getChinese()).append(",").append(s.getMath()).append(",").append(s.getEnglish()).append(",").append(s.getSum());
    
    // 调用字符缓冲输出流对象的方法写数据
    bw.write(sb.toString());
    bw.newLine();
    bw.flush();
    }
    
    //释放资源
    bw.close();
    }
    }
    • 复制单级文件夹
    • 案例需求: 把“E:\itcast”这个文件夹复制到模块目录下
  • 分析步骤
      创建数据源目录File对象,路径是E:\itcast
    1. 获取数据源目录File对象的名称
    2. 创建目的地目录File对象,路径由(模块名+第2步获取的名称)组成
    3. 判断第3步创建的File是否存在,如果不存在,就创建
    4. 获取数据源目录下所有文件的File数组
    5. 遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件
    6. 获取数据源文件File对象的名称
    7. 创建目的地文件File对象,路径由(目的地目录+第7步获取的名称)组成
    8. 复制文件
    9. 由于不清楚数据源目录下的文件都是什么类型的,所以采用字节流复制文件采用参数为File的构造方法
    /*
    需求:
    把E:\\itcast 这个文件夹复制到模块目录下
    
    思路:
    1:创建数据源目录File对象,路径是E:\\itcast
    2:获取数据源目录File对象的名称(itcast)
    3:创建目的地目录File对象,路径名是模块名+itcast组成(myCharStream\\itcast)
    4:判断目的地目录对应的File是否存在,如果不存在,就创建
    5:获取数据源目录下所有文件的File数组
    6:遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件
    数据源文件:E:\\itcast\\mn.jpg
    7:获取数据源文件File对象的名称(mn.jpg)
    8:创建目的地文件File对象,路径名是目的地目录+mn.jpg组成(myCharStream\\itcast\\mn.jpg)
    9:复制文件
    由于文件不仅仅是文本文件,还有图片,视频等文件,所以采用字节流复制文件
    */
    public class CopyFolderDemo {
    public static void main(String[] args) throws IOException {
    //创建数据源目录File对象,路径是E:\\itcast
    File srcFolder = new File("D:\\Youku\\唐唐说电影 第一季");
    
    //获取数据源目录File对象的名称(itcast)
    // String srcFolderName = srcFolder.getName();
    
    //创建目的地目录File对象,路径名是模块名+itcast组成(myCharStream\\itcast)
    File destFolder = new File("day10_code", srcFolder.getName());
    
    //判断目的地目录对应的File是否存在,如果不存在,就创建
    if(!destFolder.exists()) {
    destFolder.mkdir();
    }
    
    //获取数据源目录下所有文件的File数组
    File[] listFiles = srcFolder.listFiles();
    
    //遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件
    for(File srcFile : listFiles) {
    //数据源文件:E:\\itcast\\mn.jpg
    //获取数据源文件File对象的名称(mn.jpg)
    // String srcFileName = srcFile.getName();
    //创建目的地文件File对象,路径名是目的地目录+mn.jpg组成(myCharStream\\itcast\\mn.jpg)
    // File destFile = new File(destFolder,srcFileName);
    copyFile(destFolder, srcFile);
    }
    }
    
    private static void copyFile(File destFolder, File srcFile) throws IOException {
    //复制文件
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
    // new File(destFolder,srcFile.getName()
    // day10_code\唐唐说电影 第一季\3个80岁老头抢银行 竟然为泡妞 最年迈的劫匪-_高清
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(destFolder,srcFile.getName())));
    
    byte[] bys = new byte[1024];
    int len;
    while ((len=bis.read(bys))!=-1) {
    bos.write(bys,0,len);
    }
    
    bos.close();
    bis.close();
    }
    }
    • 复制多级文件夹
    • 案例需求

      把“E:\itcast”这个文件夹复制到 F盘目录下
  • 分析步骤

      创建数据源File对象,路径是E:\itcast
    1. 创建目的地File对象,路径是F:\
    2. 写方法实现文件夹的复制,参数为数据源File对象和目的地File对象
    3. 判断数据源File是否是文件
  • 是文件:直接复制,用字节流

  • 不是文件:

      在目的地下创建该目录
    • 遍历获取该目录下的所有文件的File数组,得到每一个File对象
    • 回到3继续(递归)
    public class CopyFile {
    public static void main(String[] args) throws IOException {
    // 数据源 E:\教学视频\第二阶段\day10\案例
    File srcFile = new File("E:\\教学视频\\第二阶段\\day10\\案例");
    // 目的地 D:\\
    File destFile = new File("D:\\");
    
    CopyFolder(srcFile, destFile);
    }
    
    private static void CopyFolder(File srcFile, File destFile) throws IOException {
    
    // 判断 源目录 是否是一个文件夹
    
    if (srcFile.isDirectory()) {
    // 创建文件夹,在目的地,还需要在拼接路径
    // D:\案例\myCharStream
    File newFile = new File(destFile, srcFile.getName());
    // 判断newFile是否是存在,如果不存在就创建文件夹
    if (!newFile.exists()) {
    newFile.mkdirs();
    }
    
    // 获取源目录下的所有的文件或文件夹
    File[] files = srcFile.listFiles();
    for (File file : files) {
    // 如果是文件,直接复制
    if (file.isFile()) {
    // 使用字节缓冲流复制文件
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(newFile,file.getName())));
    
    int len;
    byte[] bys = new byte[2048];
    while ((len = bis.read(bys)) != -1) {
    bos.write(bys,0,len);
    }
    
    // 释放资源
    bos.close();
    bis.close();
    
    }else if(file.isDirectory()){
    // 如果是文件夹,递归调用CopyFolder
    CopyFolder(file,newFile);
    }
    }
    }
    }
    }

    二.IO特殊操作流

    标准流

    • 总结:

      其实就是我们常用的 System.in 和 System.out 这两个
  • System类的类字段

      err : 标准的错误流
    • in : 标准的输入流 : 数据的来源? 键盘录入 ,经常使用在键盘录入数据
    • out : 标准的输出流 PrintStream 输出的目的是控制台
    public class SystemInDemo {
    public static void main(String[] args) throws IOException {
    
    System.err.println("这是标准的错误流!!!!!");
    
    //public static final InputStream in:标准输入流
    //        InputStream is = System.in;
    
    //        int by;
    //        while ((by=is.read())!=-1) {
    //            System.out.print((char)by);
    //        }
    
    //如何把字节流转换为字符流?用转换流
    //        InputStreamReader isr = new InputStreamReader(is);
    //        //使用字符流能不能够实现一次读取一行数据呢?可以
    //        //但是,一次读取一行数据的方法是字符缓冲输入流的特有方法
    //        BufferedReader br = new BufferedReader(isr);
    
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    
    System.out.println("请输入一个字符串:");
    String line = br.readLine();
    System.out.println("你输入的字符串是:" + line);
    
    System.out.println("请输入一个整数:");
    int i = Integer.parseInt(br.readLine());
    System.out.println("你输入的整数是:" + i);
    //
    // //自己实现键盘录入数据太麻烦了,所以Java就提供了一个类供我们使用
    Scanner sc = new Scanner(System.in);
    }
    }

    打印流

    • PrintStream 字节打印流
    • PrintStream特点: 1.只负责数据的输出,不负责数据的读取
    • 2.与其他输出流不同,PrintStream 永远不会抛出 IOException
    • 3.有特有的方法,print,println void print(任意类型的值)
    • void println(任意类型的值并换行)
  • 构造方法:
      PrintStream(File file):输出的目的地是一个文件
    • PrintStream(OutputStream out):输出的目的地是一个字节输出流
    • PrintStream(String fileName) :输出的目的地是一个文件路径

    PrintWriter:

    • PrintWriter 字符打印流

    • 打印流的特点

      自动换行 println()
    • 不能输出字节 可以输出字节以外的内容
    • 必须是通过配置 自动刷新 (println,printf,format)
      boolean autoFlush: true 自动刷新 false,不自动刷新
    • 包装流本身没有写出功能
    • 将字节输出流转换字符输出流
  • PrintWriter特有方法和构造方法

      a:PrintWriter构造方法 PrintWriter(String fileName) : 指定文件的名称并创建PrintWriter对象
    • PrintWriter(Writer out, boolean autoFlush) : 根据字符输出流,并是否开启自动刷新 创建PrintWriter对象
  • b:PrintWriter特有的方法
      void write(String s): 写一个字符串
    • void print(String s): 输出字符串, 没有换行
    • void println(String s)(掌握): 输出字符串并换行. 如果启动了自动刷新, 则会执行自动刷新写入数据
    • void printf(Locale l, String format, Object… args): 使用指定格式字符串和参数将格式化的字符串写入输出流. 如果启动了自动刷新, 则会执行自动刷新写入数据
    • void format(Locale l, String format, Object… args): 使用指定格式字符串和参数将格式化的字符串写入输出流. 如果启动了自动刷新, 则会执行自动刷新写入数据
    /*
    字符打印流的构造方法:
    PrintWriter​(String fileName) :使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新
    
    PrintWriter​(Writer out, boolean autoFlush):创建一个新的PrintWriter
    out:字符输出流
    autoFlush: 一个布尔值,如果为真,则println , printf ,或format方法将刷新输出缓冲区
    */
    public class PrintWriterDemo {
    public static void main(String[] args) throws IOException {
    //PrintWriter​(String fileName) :使用指定的文件名创建一个新的PrintWriter,而不需要自动执行行刷新
    //        PrintWriter pw = new PrintWriter("myOtherStream\\pw.txt");
    
    //        pw.write("hello");
    //        pw.write("\r\n");
    //        pw.flush();
    //        pw.write("world");
    //        pw.write("\r\n");
    //        pw.flush();
    
    //        pw.println("hello");
    /*
    pw.write("hello");
    pw.write("\r\n");
    */
    //        pw.flush();
    //        pw.println("world");
    //        pw.flush();
    
    //PrintWriter​(Writer out, boolean autoFlush):创建一个新的PrintWriter
    PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\\pw.txt"),true);
    //        PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream\\pw.txt"),false);
    
    pw.println("hello");
    /*
    pw.write("hello");
    pw.write("\r\n");
    pw.flush();
    */
    pw.println("world");
    
    pw.close();
    }
    }
    • 复制Java文件打印流改进版
    • 案例需求 把模块目录下的PrintStreamDemo.java 复制到模块目录下的 Copy.java
  • 分析步骤
      根据数据源创建字符输入流对象
    • 根据目的地创建字符输出流对象
    • 读写数据,复制文件
    • 释放资源
    public class CopyFile {
    public static void main(String[] args) throws IOException {
    // 数据源 day10_code\PrintStreamDemo.java
    BufferedReader br = new BufferedReader(new FileReader(new File("day10_code\\PrintStreamDemo.java")));
    // 目的地 day10_code\copy.java
    PrintWriter pw = new PrintWriter(new FileWriter(new File("day10_code\\copy.java")),true);
    
    String line;
    while ((line = br.readLine()) != null) {
    pw.println(line);
    }
    
    // pw.close();
    br.close();
    }
    }

    对象流

    • 对象的序列化流_ObjectOutputStream
    • 总结:

      ObjectOutputStream的作用:

    • 构造方法:
      ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。

    • 成员方法:
      void writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。

    • 使用步骤:

    • 1.创建ObjectOutputStream对象,构造方法中传递字节输出流

    • 2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中

    • 3.释放资源

    public class ObjectOutputStreamDemo01 {
    public static void main(String[] args) throws IOException {
    // 创建对象 ObjectOutputStream
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("p.txt"));
    
    // 写数据
    // 创建Person对象
    Person p = new Person("张三", 13);
    oos.writeObject(p);
    
    // 释放资源
    oos.close();
    }
    }
    
    public class Person implements Serializable {
    // ....
    }
    • 对象的反序列化流_ObjectInputStream
    • 总结:

      ObjectInputStream:对象的序列化流
      作用:

    • 构造方法:

      ObjectInputStream(InputStream in):创建从指定 InputStream 读取的 ObjectInputStream。
  • 成员方法:

      Object readObject():从 ObjectInputStream 读取对象。
  • 使用步骤:

      1.创建 ObjectInputStream 对象,构造方法中传递字节输入流
    • 2.使用 ObjectInputStream 对象中的方法 readObject() 读取保存对象的文件
    • 3.释放资源
    • 4.使用读取出来的对象(打印)
    public static void main(String[] args) {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    // method();
    // 反序列化
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("p.txt"));
    // 读取数据
    Object obj = ois.readObject();
    System.out.println(obj);
    }
    }

    #Properties集合

    • A:Properties 概述
    • B:Properties 作用
    • C:Properties 构造方法和成员方法
    • 总结:

      A:概述

      在流中或从流中加载数据的
    • 将集合中的内容,进行持久化的
  • B:作用

      经常会用于简单的配置文件

    • 特点:

      默认数据的类型是String类型的
  • 注意事项:

      创建Properties集合对象的时候,不要加泛型,它根本就不是一个泛型类
  • C:构造方法和成员方法

      a:构造方法 Properties Properties():
  • b:成员方法
      String getProperty(String key) (重点掌握):
    • String getProperty(String key, String defaultValue):
    • void setProperty(String key, String value) (重点掌握):
    • Set stringPropertyNames() 返回此属性列表中的键集,其中该键及其对应值是字符串,此方法相当于Map集合中的keySet方法
    /*
    Properties作为集合的特有方法:
    Object setProperty(String key, String value):设置集合的键和值,都是String类型,底层调用Hashtable方法put
    String getProperty(String key):使用此属性列表中指定的键搜索属性
    Set<String> stringPropertyNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
    */
    public class PropertiesDemo02 {
    public static void main(String[] args) {
    //创建集合对象
    Properties prop = new Properties();
    
    //Object setProperty(String key, String value):设置集合的键和值,都是String类型,底层调用Hashtable方法put
    prop.setProperty("itheima001", "林青霞");
    /*
    Object setProperty(String key, String value) {
    return put(key, value);
    }
    
    Object put(Object key, Object value) {
    return map.put(key, value);
    }
    */
    prop.setProperty("itheima002", "张曼玉");
    prop.setProperty("itheima003", "王祖贤");
    
    //String getProperty(String key):使用此属性列表中指定的键搜索属性
    //        System.out.println(prop.getProperty("itheima001"));
    System.out.println(prop.getProperty("itheima0011","默认值"));
    
    //        System.out.println(prop);
    
    //Set<String> stringPropertyNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
    Set<String> names = prop.stringPropertyNames();
    for (String key : names) {
    //            System.out.println(key);
    String value = prop.getProperty(key);
    System.out.println(key + "," + value);
    }
    }
    }

    Properties和IO流结合的功能

    • 常用方法

      void load(InputStream in): 将文件内容加载到properties集合中
    • void load(Reader reader): 将文件内容加载到properties集合中
    • void store(Writer writer, String comments): 将properties集合中的内容写入到文件中,并添加文件的描述
    • void store(OutputStream out, String comments):将properties集合中的内容写入到文件中,并添加文件的描述
  • 常用 Propertis的读写操作步骤

      写出到文件

      1.创建Properties集合对象,添加数据
    • 2.创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
    • 3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
    • 4.释放资源
  • 从文件读取

      1.创建Properties集合对象
    • 2.使用Properties集合对象中的方法load读取保存键值对的文件
    • 3.遍历Properties集合
  • 注意:

      1.存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号)
    • 2.存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取
    • 3.存储键值对的文件中,键与值默认都是字符串,不用再加引号
    private static void myLoad() throws IOException {
    Properties prop = new Properties();
    //void load(Reader reader):
    FileReader fr = new FileReader("day10_code\\names.properties");
    prop.load(fr);
    fr.close();
    
    String itheima001 = prop.getProperty("itheima001");
    String itheima002 = prop.getProperty("itheima002");
    System.out.println(itheima001);
    System.out.println(itheima002);
    }
    
    * 3.遍历Properties集合
    
    * 注意:
    * 1.存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号)
    * 2.存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取
    * 3.存储键值对的文件中,键与值默认都是字符串,不用再加引号
    
    ```java
    
    private static void myLoad() throws IOException {
    Properties prop = new Properties();
    //void load(Reader reader):
    FileReader fr = new FileReader("day10_code\\names.properties");
    prop.load(fr);
    fr.close();
    
    String itheima001 = prop.getProperty("itheima001");
    String itheima002 = prop.getProperty("itheima002");
    System.out.println(itheima001);
    System.out.println(itheima002);
    }
    • 点赞
    • 收藏
    • 分享
    • 文章举报
    Naker_ 发布了48 篇原创文章 · 获赞 6 · 访问量 526 私信 关注
  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: