java IO流进阶 对象处理流, 转换流, 打印流

简介: java IO流进阶——对象处理流,转换流,打印流 内容分享。

目录

一、对象处理流

       1.作用 :

       2.序列化和反序列化 :

       3.ObjectOutputStream :

               1° 概述

               2° 演示

       4.ObjectInputStream :

               1° 概述

               2° 演示

       5.关于序列化的细节 :

       6.标准输入输出流:

二、转换流

       1.概述 :

       2.InputStreamReader :

       3.OutputStreamWriter :

三、打印流

       1.PrintStream :

       2.PrintWriter :

四、Properties类内容补充

       1.拾枝杂谈 :

       2.常见方法 :

       3.代码演示 :


一、对象处理流

       1.作用 :

       既可以保存数据的值,也可以保存数据的数据类型;使得数据被保存到文件中后,还能够从文件中恢复

       eg1 : 一个基本类型数据 int i = 5; ,对象处理流可以将i变量的值5和它的数据类型int都保存到文件中;

       eg2 : 一个引用类型数据 Cat cat = new Cat("bubble", 5, "white");,对象处理流可以将cat变量的值String-"bubble", int-5, String-"white"都保存下来,还可以记录下它的数据类型是Cat类型。

       2.序列化和反序列化 :

       序列化——保存数据的值和数据类型到文件中

       反序列化——将文件中保存的数据(包含值和数据类型)重新恢复成数据本

       如下图所示 :

image.png      

PS : 若想让某个类的对象支持序列化机制,必须让该类实现可序列化,即,实现以下两个接口之一 ——

       Serializable,一个标记接口(标记接口指“没有定义方法,只做了声明”的接口),如下图所示:

image.png      

 2°Externalizable,一个继承了Serializable类的接口,并且在接口中定义了两个抽象方法,如下图所示 :

image.png      

Δ一般情况下,推荐继承第一个接口Serializable(不需要实现抽象方法)

       3.ObjectOutputStream :

               1° 概述

       ObjectOutputStream继承自OutputStream类;它可以实现数据的序列化。ObjectOutputStream类同样使用了“修饰器模式”,即该类中有一个OutputStream的引用变量(存在于OutputStream类的静态内部类BlockDataOutputStream中),如下 :

image.png      

通过ObjectOutputStream的带参构造可以传入一个OutputStream类的子类对象,以实现多态,如下所示 :

image.png      

实现多态后,可以通过动态绑定机制,调用传入类型的特有方法

               2° 演示

               up以ObjectOutputStream_Demo类作为测试类,代码如下 :

packagecsdn.knowledge.api_tools.iocurrent.object_current;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.ObjectOutputStream;
importjava.io.Serializable;
publicclassObjectOutputStream_Demo {
publicstaticvoidmain(String[] args) throwsIOException {
/*序列化之后,保存的文件格式不是纯文本。*/ObjectOutputStreamobjectOutputStream=newObjectOutputStream(newFileOutputStream("D:\\JAVA\\IDEA\\fileEX\\d1.dat"));
//写入字符串objectOutputStream.writeUTF("Cyan_RA9");
//自动装箱objectOutputStream.writeInt(141);
objectOutputStream.writeDouble(233.33);
objectOutputStream.writeChar('A');
//序列化对象objectOutputStream.writeObject(newCat("bubble", 5, "white"));
//释放资源objectOutputStream.close();
    }
}
//序列化对象的必须条件————实现Serializable接口 或 ExternalizableclassCatimplementsSerializable {
privateStringname;
privateintage;
privateStringcolor;
//建议添加该语句————//private static final long serialVersionUID = 1L;publicCat(Stringname, intage, Stringcolor) {
this.name=name;
this.age=age;
this.color=color;
    }
@OverridepublicStringtoString() {
return"Cat{"+"name='"+name+'\''+", age="+age+", color='"+color+'\''+'}';
    }
}

image.gif

               运行结果 :

image.png

               非纯文本文件使用文本编辑器打开会出现乱码,但是依然可以看出一些端倪。

       4.ObjectInputStream :

               1° 概述

       ObjectInputStream类也继承自OutputStream类;它可以实现数据的反序列化。ObjectInputStream类同样使用了“修饰器模式”,即该类中有一个InputStream的引用变量(存在于InputStream类中的静态内部类PeekInputStream中),如下 :

image.png      

通过ObjectInputStream的带参构造可以传入一个InputSream类的子类对象,以实现多态,如下所示 :

image.png      

实现多态后,可以通过动态绑定机制,调用传入类型的特有方法

               2° 演示

               up以ObjectInputStream_Demo类为演示类,代码如下 :

packagecsdn.knowledge.api_tools.iocurrent.object_current;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.io.ObjectInputStream;
publicclassObjectInputStream_Demo {
publicstaticvoidmain(String[] args) throwsIOException, ClassNotFoundException {
ObjectInputStreamobjectInputStream=newObjectInputStream(newFileInputStream("D:\\JAVA\\IDEA\\fileEX\\d1.dat"));
/*1.反序列化的顺序必须和序列化时的顺序一致,即读取数据和保存数据的顺序一致,否则会出现类型转换异常。2.更改源数据后,要重写保存,才能读取到最新时间的数据。3.必须使读取数据的类能够访问到对象的类*/System.out.println(objectInputStream.readUTF());
System.out.println(objectInputStream.readInt());
System.out.println(objectInputStream.readDouble());
System.out.println(objectInputStream.readChar());
//抛出异常System.out.println(objectInputStream.readObject());
/*PS : 若想使用子类特有的方法,需要进行类型转换。*/    }
}

image.gif

               运行结果 :

image.png

       5.关于序列化的细节 :

      序列化或者反序列化的对象必须实现实现Serializable接口;并且序列化和反序列化时写入数据与读取数据的顺序必须一致

        序列化类中,建议添加serialVersionUID,可以提高版本的兼容性

        序列化对象时,默认要将里面所有属性都进行序列化,但不包括static和transient修饰的成员

        序列化对象时,要求里面的属性的类型也要实现序列化接口。(eg : String, Integer等类已实现了序列化)

       序列化具备可继承性,即如果某个类实现了序列化,默认其所有子类也实现了序列化。(eg : Number ---> Serializable)

       6.标准输入输出流:

       System.in——标准输入,System类中的一个公有静态引用常量,编译类型是InputStream类型,默认设备是键盘。如下图所示 :

image.png        

System.out——标准输出,System类中的一个公有静态引用常量,编译类型是PrintStream类型,默认设备是显示器。如下图所示 :

image.png

       两者的运行类型如下图所示 :

image.png

PS : Scanner sc = new Scanner(System.in); 中,"System.in"实际就是一个BufferedInputStream


二、转换流

       1.概述 :

       若在txt文件中出现中文,并且该文件没有使用UTF-8形式编码;在使用IO流读取文件时就会出现乱码问题。

       转换流可以解决乱码问题,转换流可以将字节流转成字符流,同时指定读取文件时按照怎样的编码方式

       常见转换流有两个 —— InputStreamReaderOutputStreamWriter

       2.InputStreamReader :

        InputStreamReader是Reader抽象类的一个子类,因此它本身属于字符流范畴。完成转换所调用的构造器如下,需要传入一个InputStream类的子类对象,以及一个编码类型。

image.png      

以InputStreamReader_Demo类为演示类,代码如下 :

packagecsdn.knowledge.api_tools.iocurrent.transformation;
importjava.io.*;
importstaticjava.nio.charset.StandardCharsets.UTF_8;
publicclassInputStreamReader_Demo {
publicstaticvoidmain(String[] args) throwsIOException {
InputStreamReaderinputStreamReader=newInputStreamReader(newFileInputStream("D:\\JAVA\\IDEA\\file\\3.txt"), UTF_8);
BufferedReaderbufferedReader=newBufferedReader(inputStreamReader);
Stringdata;
while ((data=bufferedReader.readLine()) !=null) {
System.out.println(data);
        }
bufferedReader.close();
    }
}
image.gif

       运行结果 :

image.png

       3.OutputStreamWriter :

       OutputStreamWriter类继承自Writer类,转换方法与InputStreamWriter同理

       以OutputStreamWriter_Demo类为演示类,代码如下 :

packagecsdn.knowledge.api_tools.iocurrent.transformation;
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.OutputStreamWriter;
/*** @author : Cyan_RA9* @version : 21.0*/publicclassOutputStreamWriter_Demo {
publicstaticvoidmain(String[] args) throwsIOException {
OutputStreamWriteroutputStreamWriter=newOutputStreamWriter(newFileOutputStream("D:\\JAVA\\IDEA\\fileEX\\1.txt"), "UTF-16");
outputStreamWriter.write("Space-X, 星舰发射!");
outputStreamWriter.close();
    }
}
image.gif

       运行效果 :

image.png

三、打印流

       1.PrintStream :

       PrintStream的类图如下 :

image.png      

 PS : PrintStream间接继承自OutputStream抽象类,属于字节流

       以PrintStream_Demo类为演示类,代码如下 :

packagecsdn.advanced.io.print;
importjava.io.IOException;
importjava.io.PrintStream;
publicclassPrintStream_Demo {
publicstaticvoidmain(String[] args) throwsIOException {
//out本身是PrintStream类型PrintStreamprintStream=System.out;
//默认输出设备是显示屏printStream.println("Space-X!");
printStream.write("YYDS".getBytes());
//更改输出设备到文件System.setOut(newPrintStream("D:\\JAVA\\IDEA\\fileEX\\4.txt"));
System.out.println("这盛世,如您所愿!");
printStream.close();
    }
}
image.gif

       运行结果 :

image.png

       2.PrintWriter :

       PrintWriter的类图如下 :

image.png      

PS : PrintWriter类直接继承自Writer抽象类,属于字符流

       以PrintWriter_Demo类为演示类,代码如下 :

packagecsdn.advanced.io.print;
importjava.io.FileWriter;
importjava.io.IOException;
importjava.io.PrintWriter;
publicclassPrintWriter_Demo {
publicstaticvoidmain(String[] args) throwsIOException {
//打印到控制台PrintWriterprintWriter1=newPrintWriter(System.out);
//打印到文件(使用FileWriter的追加模式)PrintWriterprintWriter2=newPrintWriter(newFileWriter("D:\\JAVA\\IDEA\\fileEX\\4.txt", true));
printWriter1.println("嘤嘤嘤");
printWriter1.close();
printWriter2.println("嘤嘤嘤嘤嘤嘤");
printWriter2.close();
    }
}
image.gif

       运行结果 :

image.png

四、Properties类内容补充

       1.拾枝杂谈 :

       在“Hashtable源码分析及其子类Properties讲解”一文中,已有简略地介绍过Properties类。(如何导入数据,读取数据,追加数据)

       Properties类是专门用于读取配置文件的集合类,也以键值对的形式保存数据;键值对默认为String类型。

       2.常见方法 :

       load——加载配置文件的键值对到当前Properties类对象

       list——将数据显示到指定设备

       getProperty(key)——根据键获取值

      setProperty(key, value)——设置自定义键值对到Properties类对象

       store——将Properties类对象中的键值对信息存储到配置文件;在IDEA中,如果键值对中包含中文,会将中文对应的unicode码存储到配置文件。

       3.代码演示 :

               以PropertiesEX类为演示类,代码如下 :

packagecsdn.advanced.io.standart;
importjava.io.*;
importjava.util.Iterator;
importjava.util.Properties;
/*** @author : Cyan_RA9* @version : 21.0*/publicclassPropertiesEX {
publicstaticvoidmain(String[] args) throwsIOException {
Propertiesproperties=newProperties();
Readerreader=newBufferedReader(newFileReader("D:\\JAVA\\IDEA\\file\\demo2.properties"));
Writerwriter=newFileWriter("D:\\JAVA\\IDEA\\file\\demo3.properties", true);
properties.load(reader);
//listing propertiesproperties.list(System.out);    //标准输出Iterator<String>iterator=properties.stringPropertyNames().iterator();
while (iterator.hasNext()) {
Stringkey=iterator.next();
System.out.println("key = "+key+" whilst value = "+properties.getProperty(key));
        }
properties.setProperty("color", "cyan");
properties.store(writer, "try it");
reader.close();
writer.close();
    }
}

image.gif

               运行效果 :

image.png

image.png

       System.out.println("END------------------------------------------------------------------------------");

目录
相关文章
|
4月前
|
Java
深入JavaSE:详解Java对象的比较。
总的来说,Java对象的比较就像海洋生物的比较,有外在的,有内在的,有面对所有情况的,也有针对特殊情况的。理解并掌握这些比较方式,就能更好地驾驭Java的世界,游刃有余地操作Java对象。
77 12
|
5月前
|
编解码 JavaScript 前端开发
【Java进阶】详解JavaScript的BOM(浏览器对象模型)
总的来说,BOM提供了一种方式来与浏览器进行交互。通过BOM,你可以操作窗口、获取URL、操作历史、访问HTML文档、获取浏览器信息和屏幕信息等。虽然BOM并没有正式的标准,但大多数现代浏览器都实现了相似的功能,因此,你可以放心地在你的JavaScript代码中使用BOM。
147 23
|
5月前
|
Java 数据安全/隐私保护
Java 类和对象
本文介绍了Java编程中类和对象的基础知识,作为面向对象编程(OOP)的核心概念。类是对象的蓝图,定义实体类型;对象是具体实例,包含状态和行为。通过示例展示了如何创建表示汽车的类及其实例,并说明了构造函数、字段和方法的作用。同时,文章还探讨了访问修饰符的使用,强调封装的重要性,如通过getter和setter控制字段访问。最后总结了类与对象的关系及其在Java中的应用,并建议进一步学习继承等概念。
117 1
|
6月前
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
235 23
|
6月前
|
设计模式 缓存 Java
重学Java基础篇—Java对象创建的7种核心方式详解
本文全面解析了Java中对象的创建方式,涵盖基础到高级技术。包括`new关键字`直接实例化、反射机制动态创建、克隆与反序列化复用对象,以及工厂方法和建造者模式等设计模式的应用。同时探讨了Spring IOC容器等框架级创建方式,并对比各类方法的适用场景与优缺点。此外,还深入分析了动态代理、Unsafe类等扩展知识及注意事项。最后总结最佳实践,建议根据业务需求选择合适方式,在灵活性与性能间取得平衡。
327 3
|
5月前
|
存储 缓存 Java
理解Java引用数据类型:它们都是对象引用
本文深入探讨了Java中引用数据类型的本质及其相关特性。引用变量存储的是对象的内存地址而非对象本身,类似房子的地址而非房子本身。文章通过实例解析了引用赋值、比较(`==`与`equals()`的区别)以及包装类缓存机制等核心概念。此外,还介绍了Java引用类型的家族,包括类、接口、数组和枚举。理解这些内容有助于开发者避免常见错误,提升对Java内存模型的掌握,为高效编程奠定基础。
238 0
|
5月前
|
Java
java中一个接口A,以及一个实现它的类B,一个A类型的引用对象作为一个方法的参数,这个参数的类型可以是B的类型吗?
本文探讨了面向对象编程中接口与实现类的关系,以及里氏替换原则(LSP)的应用。通过示例代码展示了如何利用多态性将实现类的对象传递给接口类型的参数,满足LSP的要求。LSP确保子类能无缝替换父类或接口,不改变程序行为。接口定义了行为规范,实现类遵循此规范,从而保证了多态性和代码的可维护性。总结来说,接口与实现类的关系天然符合LSP,体现了多态性的核心思想。
112 0
|
6月前
|
存储 算法 安全
Java对象创建和访问
Java对象创建过程包括类加载检查、内存分配(指针碰撞或空闲列表)、内存初始化、对象头设置及初始化方法执行。访问方式有句柄和直接指针两种,前者稳定但需额外定位,后者速度快。对象创建涉及并发安全、垃圾回收等机制。
Java对象创建和访问
|
8月前
|
安全 Java
Object取值转java对象
通过本文的介绍,我们了解了几种将 `Object`类型转换为Java对象的方法,包括强制类型转换、使用 `instanceof`检查类型和泛型方法等。此外,还探讨了在集合、反射和序列化等常见场景中的应用。掌握这些方法和技巧,有助于编写更健壮和类型安全的Java代码。
443 17
|
7月前
|
存储 Java
Java中判断一个对象是否是空内容
在 Java 中,不同类型的对象其“空内容”的定义和判断方式各异。对于基本数据类型的包装类,空指对象引用为 null;字符串的空包括 null、长度为 0 或仅含空白字符,可通过 length() 和 trim() 判断;集合类通过 isEmpty() 方法检查是否无元素;数组的空则指引用为 null 或长度为 0。