IO基础之对象流、打印流、标准的IO和扫描器类的简单说明
2017-08-01 19:14
453 查看
对象流:(序列化和反序列化)
序列化:指把堆内存中的Java对象数据,通过某种方式把对象存储到磁盘文件中或者传递给其他的网络节点(在网络上传输)我们把这个过程称之为序列化。
反序列化:把磁盘文件中的对象数据或者把网络节点的对象数据,恢复成Java对象的过程。
为什么需要序列化:
1、在分布式系统中,需要共享数据的JavaBean对象,都得做序列化,此时下需要把对象在网络上传输,此时就得把对象数据转换为二进制形式。
以后存储在HttpSession中的对象,都应该实现序列化接口(只有实现序列化接口的类,才能做序列化操作)。
2、服务钝化:如果服务发现某些对象好久都没有活动了,此时服务器就会把这些内存中的对象,持久化在本地磁盘文件中(Java对象-->二进制文件)。
如果某些对象需要活动的时候,先在内存中去寻找,找到就使用。找不到再去磁盘文件中,反序列化我们的对象数据,恢复成Java对象。
需要做序列化的对象的类,必须实现序列化接口:java.io.Serializable接口(标志接口[没有抽象方法])
底层会做判断,如果当前对象是Serializable的实例,才允许做序列化:boolean ret = java对象 instanceof Serializable;
在Java中大多数类都已经实现Serializable接口。
使用对象流来完成序列化和反序列化操作:
ObjectOutputStream:通过writeObject方法做序列化操作的;
ObjectInputStream:通过readObject方法做反序列化操作的。
准备一个Person类:
对象流序列化操作:
运行结果:
做反序列化操作必须存在对象的字节码对象。
序列化的细节,序列化的版本:
1、如果某些数据不需要做序列化,比如密码,该怎么做?
理论上说,静态的字段和瞬态的字段是不能做序列化操作的。
解决方案:给该字段加上一个修饰符:transient
2、序列化的版本问题:
反序列化Java对象时必须提供该对象的class文件,现在问题是,随着项目的升级,系统的class文件也会升级(增加一个字段,或删除一个字段),
这是如何保证两个class文件的兼容性?
Java通过serialVersionUID(序列化版本号)来判断字节码是否发生改变。如果不显示定义serialVersionUID类变量,该类变量的值由JVM根据类相关信息计算,而修改后的类计算方式和之前往往不同。
解决方案:在类中提供一个固定的serialVersionUID。
private static final long serialVersionUID = 1L;
打印流:打印数据的,打印流只能是输出流
PrintStream:字节打印流
PrintWriter:字符打印流
对于PrintWriter来说,当启用字段刷新之后,
PrintWriter pw = new PrintWriter(new FileOututStream(new File("file/out")),true);
调用println、或者printf、或者format方法,便会立马刷新操作
如果没有开启自动刷新,则需要手动刷新或者当缓冲区满的时候,再自动刷新
使用打印流作为输出流,此时的输出操作会特别简单因为在打印流中:
提供了print方法:打印不换行
提供了println方法:打印再换行
print和println方法可以支持打印输出各种数据类型的数据,记住void println(Object x)即可。
字节打印流:
字符打印流:
打印流中的格式化输出(printf方法):
System.out.println();其实等价于PrintStream ps = System.out; ps.println();
运行结果:
标准的IO:
标准的输入:通过键盘录入数据给程序
标准的输出:在屏幕上显示程序的数据
在System类中有两个常量:
InputStream in = System.in;
PrintStream out = System.out;
标准流的重定向操作:
标准的输入:通过键盘录入数据给程序;
重新指定输入的源不再是键盘,而是一个文件。
static void setIn(InputStream in);重新分配“标准”输入流。
此后,System.in数据的来源就是通过setIn指定的源。
标准的输出:在屏幕上显示程序的数据
重新指定输出的目标不再是屏幕,而是一个文件。
static void setOut(PrintStream out);重新分配“标准”输出流。
Scanner:扫描类,在java.util包中,表示输入的操作
存在的方法:xxx表示数据类型,如byte,int,boolean等;
boolean hasNextXxx();//判断是否有下一种类型的数据
Xxx nextXxx();//获取下一个该类型的数据。
序列化:指把堆内存中的Java对象数据,通过某种方式把对象存储到磁盘文件中或者传递给其他的网络节点(在网络上传输)我们把这个过程称之为序列化。
反序列化:把磁盘文件中的对象数据或者把网络节点的对象数据,恢复成Java对象的过程。
为什么需要序列化:
1、在分布式系统中,需要共享数据的JavaBean对象,都得做序列化,此时下需要把对象在网络上传输,此时就得把对象数据转换为二进制形式。
以后存储在HttpSession中的对象,都应该实现序列化接口(只有实现序列化接口的类,才能做序列化操作)。
2、服务钝化:如果服务发现某些对象好久都没有活动了,此时服务器就会把这些内存中的对象,持久化在本地磁盘文件中(Java对象-->二进制文件)。
如果某些对象需要活动的时候,先在内存中去寻找,找到就使用。找不到再去磁盘文件中,反序列化我们的对象数据,恢复成Java对象。
需要做序列化的对象的类,必须实现序列化接口:java.io.Serializable接口(标志接口[没有抽象方法])
底层会做判断,如果当前对象是Serializable的实例,才允许做序列化:boolean ret = java对象 instanceof Serializable;
在Java中大多数类都已经实现Serializable接口。
使用对象流来完成序列化和反序列化操作:
ObjectOutputStream:通过writeObject方法做序列化操作的;
ObjectInputStream:通过readObject方法做反序列化操作的。
准备一个Person类:
import java.io.Serializable; /** * Created by Layne_Yao on 2017-7-29 下午4:49:43. * CSDN:http://blog.csdn.net/Jsagacity */ public class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private String sex; private transient String password;//无需序列化 private int age; public Person(String name, String sex, String password, int age) { this.name = name; this.sex = sex; this.password = password; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", sex=" + sex + ", password=" + password + ", age=" + age + "]"; } }
对象流序列化操作:
/** * Created by Layne_Yao on 2017-7-29 下午4:49:25. * CSDN:http://blog.csdn.net/Jsagacity */ public class ObjectStreamDemo { public static void main(String[] args) throws Exception { File file = new File("obj.txt"); writeObject(file); readObject(file); } // 序列化操作 private static void writeObject(File file) throws Exception { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream( file)); out.writeObject(new Person("Layne", "man","123456", 20)); out.close(); } //反序列化操作 private static void readObject(File file) throws Exception { ObjectInputStream in = new ObjectInputStream(new FileInputStream( file)); Person person = (Person) in.readObject(); System.out.println(person); in.close(); } }
运行结果:
做反序列化操作必须存在对象的字节码对象。
序列化的细节,序列化的版本:
1、如果某些数据不需要做序列化,比如密码,该怎么做?
理论上说,静态的字段和瞬态的字段是不能做序列化操作的。
解决方案:给该字段加上一个修饰符:transient
2、序列化的版本问题:
反序列化Java对象时必须提供该对象的class文件,现在问题是,随着项目的升级,系统的class文件也会升级(增加一个字段,或删除一个字段),
这是如何保证两个class文件的兼容性?
Java通过serialVersionUID(序列化版本号)来判断字节码是否发生改变。如果不显示定义serialVersionUID类变量,该类变量的值由JVM根据类相关信息计算,而修改后的类计算方式和之前往往不同。
解决方案:在类中提供一个固定的serialVersionUID。
private static final long serialVersionUID = 1L;
打印流:打印数据的,打印流只能是输出流
PrintStream:字节打印流
PrintWriter:字符打印流
对于PrintWriter来说,当启用字段刷新之后,
PrintWriter pw = new PrintWriter(new FileOututStream(new File("file/out")),true);
调用println、或者printf、或者format方法,便会立马刷新操作
如果没有开启自动刷新,则需要手动刷新或者当缓冲区满的时候,再自动刷新
使用打印流作为输出流,此时的输出操作会特别简单因为在打印流中:
提供了print方法:打印不换行
提供了println方法:打印再换行
print和println方法可以支持打印输出各种数据类型的数据,记住void println(Object x)即可。
字节打印流:
public class PrintStreamDemo { public static void main(String[] args) throws Exception { PrintStream ps = new PrintStream(new File("file/out.txt")); ps.write("ABC".getBytes()); ps.print(false); ps.print(18); ps.print("layne"); //其实可以不用刷新 ps.close(); } }
字符打印流:
public class PrintWriterDemo { public static void main(String[] args) throws Exception { PrintWriter ps = new PrintWriter(new File("file/out.txt")); ps.write("ABC"); ps.print(false); ps.println(18); ps.print("layne"); //其实可以不用刷新 ps.close(); } }
打印流中的格式化输出(printf方法):
System.out.println();其实等价于PrintStream ps = System.out; ps.println();
//Java的格式化输出 public class printfDemo { public static void main(String[] args) { //打印一句话,效果:姓名:layne,年龄:18 String name = "layne"; int age = 18; //传统的打印风格 String str = "姓名:"+name+",年龄:"+age; System.out.println(str); //格式化输出 String format = "姓名:%s,年龄:%d"; Object[] data = {name,age}; System.out.printf(format,data); System.out.println(); //简化 System.out.printf("姓名:%s,年龄:%d",name,age); } }
运行结果:
标准的IO:
标准的输入:通过键盘录入数据给程序
标准的输出:在屏幕上显示程序的数据
在System类中有两个常量:
InputStream in = System.in;
PrintStream out = System.out;
标准流的重定向操作:
标准的输入:通过键盘录入数据给程序;
重新指定输入的源不再是键盘,而是一个文件。
static void setIn(InputStream in);重新分配“标准”输入流。
此后,System.in数据的来源就是通过setIn指定的源。
标准的输出:在屏幕上显示程序的数据
重新指定输出的目标不再是屏幕,而是一个文件。
static void setOut(PrintStream out);重新分配“标准”输出流。
public class SystemIODemo { public static void main(String[] args) throws Exception { // 重定向标准输入流 System.setIn(new FileInputStream("file/123_copy.txt")); //重定向标准输出流 System.setOut(new PrintStream("file/print.txt")); System.out.println("...开始..."); int data = System.in.read(); //读取文件123_copy.txt中的第一个字节 System.out.println(data); System.out.println("...结束..."); } }
Scanner:扫描类,在java.util包中,表示输入的操作
存在的方法:xxx表示数据类型,如byte,int,boolean等;
boolean hasNextXxx();//判断是否有下一种类型的数据
Xxx nextXxx();//获取下一个该类型的数据。
public class ScannerDemo { public static void main(String[] args) throws Exception { //扫描文件中的数据 //Scanner sc = new Scanner(new File("file/ch.txt"),"GBK"); //扫描键盘输入的数据 //Scanner sc = new Scanner(System.in); //扫描字符串的数据 Scanner sc = new Scanner("这是扫描类,我是即将被扫描的数据!!!"); while(sc.hasNextLine()){ String line = sc.nextLine(); System.out.println(line); } } }
相关文章推荐
- 黑马程序员——JAVA基础——IO(一)---流概述,节点流、处理流、转换流与标准输入输出流、打印流、File文件对象、合并流
- 【幻化万千戏红尘】qianfengDay19-java基础学习:转换流、对象流、打印流、三大标准(重定向)
- day19 IO-2 包装流 标准输入输出流 打印流 Properties 对象流和序列化
- Java基础---IO(二)--Properties类、打印流、序列流、对象操作流、数据输入输出流
- Java基础 - 序列流,内存输出流,随机访问流,对象操作流,数据输入输出流,打印流,标准输入输出流,Properties
- IO基础之Properties类、数据流、RandomAccessFile类、管道流和nio的简单说明
- IO基础之File类的简单说明
- HibernateCRUD基础框架(3)-简单的和较为复杂的标准的CRUD API
- 【OC学习-28】自定义对象的归档和解归档:例子说明以及简单总结
- java基础8:properties集合,序列化,打印流,commons-IO,对应案例
- 【转】不被重视的基础,简单高效地使用ADO.net连接对象
- 一、javaSE (二十二)登录注册IO版本案例、数据操作流、内存操作流、打印流、标准输入输出流、随机访问流、合并流、序列化流、Properties、NIO
- C++语言基础 例程 类和对象的简单应用举例
- 编写一段程序,从标准输入读取string对象的序列直到连续出现两个相同的单词或者所有单词都读完为止。使用while循环一次读取一个单词,当一个单词连续出现两次是使用break语句终止循环。输出连续重复出现的单词,或者输出一个消息说明没有人任何单词是重复出现的。
- 黑马程序员——Java基础----IO(File类、Properties类、打印流、序列流、合并流)(3)
- DirectShow_基础与简单示例说明
- JavaSE8基础 函数返回一个匿名对象 简单示例
- Linux基础管理—— " 标准IO、重定向及管道 "
- HibernateCRUD基础框架(3)-简单的和较为复杂的标准的CRUD API
- Java File类的简单说明与使用 -- Java 基础