目录
8 serialVersionUID&transient【应用】
1 标准输入流【应用】
System
类中有两个静态的成员变量
public static fifinal InputStream in
:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的
另一个输入源
public static fifinal PrintStream out
:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的
另一个输出目标
自己实现键盘录入数据
public class
SystemInDemo
{
public static
void
main
(
String
[]
args
)
throws
IOException
{
//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
);
}
}
2 标准输出流【应用】
System
类中有两个静态的成员变量
public static fifinal InputStream in
:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的
另一个输入源
public static fifinal PrintStream out
:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的
另一个输出目标
输出语句的本质:是一个标准的输出流
PrintStream ps = System.out;
PrintStream
类有的方法,
System.out
都可以使用
示例代码
public class
SystemOutDemo
{
public static
void
main
(
String
[]
args
) {
//public static final PrintStream out
:标准输出流
PrintStream ps
=
System
.
out
;
//
能够方便地打印各种数据值
// ps.print("hello");
// ps.print(100);
// ps.println("hello");
// ps.println(100);
//System.out
的本质是一个字节输出流
System
.
out
.
println
(
"hello"
);
System
.
out
.
println
(
100
);
System
.
out
.
println
();
// System.out.print();
}
}
3 字节打印流【应用】
打印流分类
字节打印流:
PrintStream
字符打印流:
PrintWriter
打印流的特点
只负责输出数据,不负责读取数据
永远不会抛出
IOException
有自己的特有方法
字节打印流
PrintStream(String fifileName)
:使用指定的文件名创建新的打印流
使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
可以改变输出语句的目的地
public static void setOut(PrintStream out)
:重新分配
“
标准
”
输出流
示例代码
public class
PrintStreamDemo
{
public static
void
main
(
String
[]
args
)
throws
IOException
{
//PrintStream(String fileName)
:使用指定的文件名创建新的打印流
PrintStream ps
=
new
PrintStream
(
"myOtherStream\\ps.txt"
);
//
写数据
//
字节输出流有的方法
// ps.write(97);
//
使用特有方法写数据
// ps.print(97);
// ps.println();
// ps.print(98);
ps
.
println
(
97
);
ps
.
println
(
98
);
//
释放资源
ps
.
close
();
}
}
4 字符打印流【应用】
字符打印流构造房方法
示例代码
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
();
}
}
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
();
}
}
6 对象序列化流【应用】
对象序列化介绍
对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存
储的属性等信息
字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
对象序列化流:
ObjectOutputStream
将
Java
对象的原始数据类型和图形写入
OutputStream
。 可以使用
ObjectInputStream
读取(重构)对
象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或
另一个进程中重构对象
构造方法
序列化对象的方法
示例代码
学生类
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
;
}
@Override
public
String
toString
() {
return
"Student{"
+
"name='"
+
name
+
'\''
+
", 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
是一个标记接口,实现该接口,不需要重写任何方法
7 对象反序列化流【应用】
对象反序列化流:
ObjectInputStream
ObjectInputStream
反序列化先前使用
ObjectOutputStream
编写的原始数据和对象
构造方法
反序列化对象的方法
示例代码
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 serialVersionUID&transient【应用】
serialVersionUID
用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
会出问题,会抛出
InvalidClassException
异常
如果出问题了,如何解决呢?
重新序列化
给对象所属的类加一个
serialVersionUID
private static fifinal 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
();
}
}