Java文件操作、IO流4

简介: Java文件操作、IO流4

8.4 字符打印流

字符打印流构造房方法

20.png

示例代码

   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();
      }
  }


8.5 复制Java文件打印流改进版

  • 案例需求
  • 把模块目录下的PrintStreamDemo.java 复制到模块目录下的 Copy.java
  • 分析步骤
  • 根据数据源创建字符输入流对象
  • 根据目的地创建字符输出流对象
  • 读写数据,复制文件
  • 释放资源
  • 代码实现
  public class CopyJavaDemo {
      public static void main(String[] args) throws IOException {
          /*
          //根据数据源创建字符输入流对象
          BufferedReader br = new BufferedReader(new FileReader("myOtherStream/PrintStreamDemo.java"));
          //根据目的地创建字符输出流对象
          BufferedWriter bw = new BufferedWriter(new FileWriter("myOtherStream/Copy.java"));
          //读写数据,复制文件
          String line;
          while ((line=br.readLine())!=null) {
              bw.write(line);
              bw.newLine();
              bw.flush();
          }
          //释放资源
          bw.close();
          br.close();
          */
          //根据数据源创建字符输入流对象
          BufferedReader br = new BufferedReader(new FileReader("myOtherStream/PrintStreamDemo.java"));
          //根据目的地创建字符输出流对象
          PrintWriter pw = new PrintWriter(new FileWriter("myOtherStream/Copy.java"),true);
          //读写数据,复制文件
          String line;
          while ((line=br.readLine())!=null) {
              pw.println(line);
          }
          //释放资源
          pw.close();
          br.close();
      }
  }


8.6 对象序列化流

  • 对象序列化介绍


       对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象

        这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对       象的数据和对象中存储的属性等信息

       字节序列写到文件之后,相当于文件中持久保存了一个对象的信息

       反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化

       对象序列化流: ObjectOutputStream


将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象


构造方法

21.png

序列化对象的方法

22.png

示例代码

  • 学生类
public class Student implements Serializable {
    private String name;
  private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

测试类

public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream/oos.txt"));
        //创建对象
        Student s = new Student("林青霞",30);
        //void writeObject(Object obj):将指定的对象写入ObjectOutputStream
        oos.writeObject(s);
        //释放资源
        oos.close();
    }
}


注意事项

  • 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
  • Serializable是一个标记接口,实现该接口,不需要重写任何方法


8.7 对象反序列化流

  • 对象反序列化流: ObjectInputStream
  • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
  • 构造方法

23.png

反序列化对象的方法

24.png

示例代码

  public class ObjectInputStreamDemo {
      public static void main(String[] args) throws IOException, ClassNotFoundException {
          //ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
          ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream/oos.txt"));
          //Object readObject():从ObjectInputStream读取一个对象
          Object obj = ois.readObject();
          Student s = (Student) obj;
          System.out.println(s.getName() + "," + s.getAge());
          ois.close();
      }
  }


8.8 serialVersionUID&transient

serialVersionUID


用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?

会出问题,会抛出InvalidClassException异常

如果出问题了,如何解决呢?

重新序列化

给对象所属的类加一个serialVersionUID

private static final long serialVersionUID = 42L;


  • transient
  • 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
  • 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
  • 示例代码
  • 学生类
public class Student implements Serializable {
    private static final long serialVersionUID = 42L;
    private String name;
//    private int age;
    private transient int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
//    @Override
//    public String toString() {
//        return "Student{" +
//                "name='" + name + '\'' +
//                ", age=" + age +
//                '}';
//    }
}

测试类

public class ObjectStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
//        write();
        read();
    }
    //反序列化
    private static void read() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream/oos.txt"));
        Object obj = ois.readObject();
        Student s = (Student) obj;
        System.out.println(s.getName() + "," + s.getAge());
        ois.close();
    }
    //序列化
    private static void write() throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream/oos.txt"));
        Student s = new Student("林青霞", 30);
        oos.writeObject(s);
        oos.close();
    }
}


9. Properties集合

9.1 Properties作为Map集合的使用

  • Properties介绍
  • 是一个Map体系的集合类
  • Properties可以保存到流中或从流中加载
  • 属性列表中的每个键及其对应的值都是一个字符串
  • Properties基本使用
  public class PropertiesDemo01 {
      public static void main(String[] args) {
          //创建集合对象
  //        Properties<String,String> prop = new Properties<String,String>(); //错误
          Properties prop = new Properties();
          //存储元素
          prop.put("itheima001", "林青霞");
          prop.put("itheima002", "张曼玉");
          prop.put("itheima003", "王祖贤");
          //遍历集合
          Set<Object> keySet = prop.keySet();
          for (Object key : keySet) {
              Object value = prop.get(key);
              System.out.println(key + "," + value);
          }
      }
  }

 

9.2 Properties作为Map集合的特有方法

特有方法

25.png

示例代码

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);
        }
    }
}


9.3 Properties和IO流相结合的方法

  • 和IO流结合的方法

    26.png
  • 示例代码
  public class PropertiesDemo03 {
      public static void main(String[] args) throws IOException {
          //把集合中的数据保存到文件
  //        myStore();
          //把文件中的数据加载到集合
          myLoad();
      }
      private static void myLoad() throws IOException {
          Properties prop = new Properties();
          //void load(Reader reader):
          FileReader fr = new FileReader("myOtherStream/fw.txt");
          prop.load(fr);
          fr.close();
          System.out.println(prop);
      }
      private static void myStore() throws IOException {
          Properties prop = new Properties();
          prop.setProperty("itheima001","林青霞");
          prop.setProperty("itheima002","张曼玉");
          prop.setProperty("itheima003","王祖贤");
          //void store(Writer writer, String comments):
          FileWriter fw = new FileWriter("myOtherStream/fw.txt");
          prop.store(fw,null);
          fw.close();
      }
  }


9.4 游戏次数案例

  • 案例需求
  • 实现猜数字小游戏只能试玩3次,如果还想玩,提示:游戏试玩已结束,想玩请充值(www.itcast.cn)

分析步骤


写一个游戏类,里面有一个猜数字的小游戏


写一个测试类,测试类中有main()方法,main()方法中写如下代码:


从文件中读取数据到Properties集合,用load()方法实现

   文件已经存在:game.txt  里面有一个数据值:count=0

通过Properties集合获取到玩游戏的次数

判断次数是否到到3次了

   如果到了,给出提示:游戏试玩已结束,想玩请充值(www.itcast.cn) 如果不到3次:   次数+1,重新写回文件,用Properties的store()方法实现玩游戏

代码实现

public class PropertiesTest {
    public static void main(String[] args) throws IOException {
        //从文件中读取数据到Properties集合,用load()方法实现
        Properties prop = new Properties();
        FileReader fr = new FileReader("myOtherStream/game.txt");
        prop.load(fr);
        fr.close();
        //通过Properties集合获取到玩游戏的次数
        String count = prop.getProperty("count");
        int number = Integer.parseInt(count);
        //判断次数是否到到3次了
        if(number >= 3) {
            //如果到了,给出提示:游戏试玩已结束,想玩请充值(www.itcast.cn)
            System.out.println("游戏试玩已结束,想玩请充值(www.itcast.cn)");
        } else {
            //玩游戏
            GuessNumber.start();
            //次数+1,重新写回文件,用Properties的store()方法实现
            number++;
            prop.setProperty("count",String.valueOf(number));
            FileWriter fw = new FileWriter("myOtherStream/game.txt");
            prop.store(fw,null);
            fw.close();
        }
    }
}


相关文章
|
11月前
|
监控 Java API
现代 Java IO 高性能实践从原理到落地的高效实现路径与实战指南
本文深入解析现代Java高性能IO实践,涵盖异步非阻塞IO、操作系统优化、大文件处理、响应式网络编程与数据库访问,结合Netty、Reactor等技术落地高并发应用,助力构建高效可扩展的IO系统。
312 0
|
8月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
313 1
|
10月前
|
Java 测试技术 API
Java IO流(二):文件操作与NIO入门
本文详解Java NIO与传统IO的区别与优势,涵盖Path、Files类、Channel、Buffer、Selector等核心概念,深入讲解文件操作、目录遍历、NIO实战及性能优化技巧,适合处理大文件与高并发场景,助力高效IO编程与面试准备。
|
11月前
|
存储 Java Linux
操作系统层面视角下 Java IO 的演进路径及核心技术变革解析
本文从操作系统层面深入解析Java IO的演进历程,涵盖BIO、NIO、多路复用器及Netty等核心技术。分析各阶段IO模型的原理、优缺点及系统调用机制,探讨Java如何通过底层优化提升并发性能与数据处理效率,全面呈现IO技术的变革路径与发展趋势。
228 3
|
11月前
|
监控 Java API
Java语言按文件创建日期排序及获取最新文件的技术
这段代码实现了文件创建时间的读取、文件列表的获取与排序以及获取最新文件的需求。它具备良好的效率和可读性,对于绝大多数处理文件属性相关的需求来说足够健壮。在实际应用中,根据具体情况,可能还需要进一步处理如访问权限不足、文件系统不支持某些属性等边界情况。
462 14
|
10月前
|
SQL Java 数据库连接
Java IO流(一):字节流与字符流基础
本文全面解析Java IO流,涵盖字节流、字符流及其使用场景,帮助开发者理解IO流分类与用途,掌握文件读写、编码转换、异常处理等核心技术,通过实战案例提升IO编程能力。
|
12月前
|
存储 Java 数据安全/隐私保护
Java技术栈揭秘:Base64加密和解密文件的实战案例
以上就是我们今天关于Java实现Base64编码和解码的实战案例介绍。希望能对你有所帮助。还有更多知识等待你去探索和学习,让我们一同努力,继续前行!
683 5
|
11月前
|
存储 Java 编译器
深入理解Java虚拟机--类文件结构
本内容介绍了Java虚拟机与Class文件的关系及其内部结构。Class文件是一种与语言无关的二进制格式,包含JVM指令集、符号表等信息。无论使用何种语言,只要能生成符合规范的Class文件,即可在JVM上运行。文章详细解析了Class文件的组成,包括魔数、版本号、常量池、访问标志、类索引、字段表、方法表和属性表等,并说明其在Java编译与运行过程中的作用。
307 0
|
11月前
|
存储 人工智能 Java
java之通过Http下载文件
本文介绍了使用Java实现通过文件链接下载文件到本地的方法,主要涉及URL、HttpURLConnection及输入输出流的操作。
742 0
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现