复习一下 TIJ 做一下IO的笔记 把以前的笔记转到Blog上
在core java上就把IO分成了 流和文件 这两个最最基本和最根源的类型
流就是对字节的操作 文件就是对文件和目录的操作
也就是说 File是在文件系统里 在不打开文件的情况下的操作 流是对文件的内容的操作
基础 & File类
tips
' File可以是任何文件或者是文件夹
' java 是用 "/“ 来做结合字母做转义字符 因此路径要用 "//" 来分隔 File f=new File("e://**//******")
' File类有常量 separator来表示分隔符 在linux下为 "/" 在win下为"/" 这个separator是string类型的
还有一个 separatorChar是char类型的
' File.separator 表示了当前的根目录
' File(File parent, String child)
根据 parent 抽象路径名和 child 路径名字符串创建一个新 File
实例。
File dir
=
new
File(File.separator);
Stirng str
=
"
one
"
+
File.separator
+
"
two.txt
"
;
File f
=
new
File(dir, str);
f.createNewFile();
' 删除方法 delete() deleteOnExit()是在程序终止的时候删除文件
' createTempFile 是在缺省的temp目录下创建 临时文件 并赋值 构造的时候可指定前缀名和后缀名
' list() 返回目录内的文件和文件夹名称的 String[]
' FileNameFilter() 文件名过滤器接口 里面有accept方法 File的list()有能力来callback 它
String的 indexOf(string s)方法 返回此字符串的索引 如果没有返回 -1
因此 过滤文件名的时候可以这么写
File fdir
=
new
File(File.separator);
String s
=
"
lessons
"
+
File.separator
+
"
ssdf
"
+
File.separator
+
"
09
"
;
File f
=
new
File(fdir,s);
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
String[] names
=
f.list(
new
FilenameFilter()
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public boolean accept(File dir, String name)...{
return name.indexOf(".java") != -1;
}
}
);
for
(
int
j
=
0
; j
<
names.length; j
++
)
System.out.println(names[j]);
也可以像TIJ 上那样写的 再写个实现了FilenamFilter的类 作为list()的参数
eg:对文件夹的操作 列出所有文件
FileTest.java
import
java.io.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
class
FileTest
...
{
public static void main(String[] args) throws Exception
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//*
//File f = new File("1.txt");
//f.createNewFile();
//f.mkdir(); //创建文件夹
//file的另一种方法,指定路径
//File f = new File("E:/lessons/sunxin/09/1.txt"); /注意用双反斜杠
//f.createNewFile();
File f = new File(File.separator);//创建文件分割符,代表当前的目录所在的盘符
String s = "lessons" + File.separator + "sunxin" + File.separator + "09" +File.separator+"1.txt";
//路径的设置 是一个string类型的(中间注意要加上分割符)
//file的另一个构造方法
File f2 = new File(f, s);//在当前目录下创建
f2.createNewFile();
//f2.delete();
f2.deleteOnExit(); //在程序退出的时候删除文件
Thread.sleep(13000);
*/
File fdir = new File(File.separator);
String s = "test" + File.separator +"lessons" + File.separator + "sunxin" + File.separator + "09";
File f = new File(fdir,s);
//利用list方法返回的是string类的数组,但是filenamefilter是一个接口
//用匿名类
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
String[] names = f.list(new FilenameFilter()...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public boolean accept(File dir, String name)...{
return name.indexOf(".java") != -1;
}
});
for(int j = 0; j < names.length; j++)
System.out.println(names[j]);
}
}
流类
流类用不同的分法可以分为不同的类
可分为 输入流和输出流
可分为 节点流和过滤流 管道流
还可以分为 字节流和字符流
最重要和最基础的类和方法
OutputStream 所有输出流&字节流的超类
提供最基本的输出方法write()和刷新输出流的方法flush() 关闭方法close()
InputStream 所有输入流&字节流的超类
提供一些基本的读入方法 read() 重定位reset()等等方法
在lang包里有一个经常用到的System里提供了两个标准的输入和输出流in和out分别是InputStream和PrintStream
一个例子 在cmd里等待输入 并在回车后打印出来
import
java.io.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
Test
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String[] args)throws Exception
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
int h;
while((h=System.in.read())!=-1)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
System.out.write(h);
}
}
}
write(int b)
将指定的字节写入此输出流。write
的常规协定是:向输出流写入一个字节。要写入的字节是参数 b
的八个低位。b
的 24 个高位将被忽略。
read()
从输入流读取下一个数据字节。返回 0
到 255
范围内的 int
字节值。如果因已到达流末尾而没有可用的字节,则返回值 -1
。在输入数据可用、检测到流的末尾或者抛出异常前,此方法一直阻塞。
这个程序在运行的时候是这样的
在命令行里输入的字符read方法会得到字符的默认编码下的int
比如输入一个w 会得到一个01110111 也就是一个字节的十六进制的77 十进制的119 然后在write的时候将这个int的低8位写入一个字节 因为使用的是PrintStream的write 所以将会使用系统默认的字符集转换并输出字符
再比如输入的是一个 "王" 得到的是 205 245 也就是二进制的 11001101 11110101 然后用字符集转换输出
我机器的系统默认字符集使用的是GBK 所以在输出的时候没有发生乱码
分类中按节点流 过滤流来分比较好 其他的类型都比较好理解
在OutputStream中 有很多子类
其中FilterOutputStream及其子类都是是过滤流
其他的FileOutputStream 等是节点流 PipedOutputStream是管道流(用于线程间的通信)
FileOutputStream是对文件的流的写操作
分别举例 创建文本文件并写入数据
import
java.io.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
class
StreamTest
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static void main(String[] args) throws Exception...{
FileOutputStream f1 = new FileOutputStream("1.rmvb");
f1.write("http://www.rainytooo.com".getBytes());
f1.close();
}
}
用文本编辑器打开可以看到字符串
再看看几个过滤流的作用
import
java.io.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
class
StreamTest
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static void main(String[] args) throws Exception...{
FileOutputStream f1 = new FileOutputStream("1.rmvb");
BufferedOutputStream bf = new BufferedOutputStream(f1);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
bf.write("http://www.rainytooo.com".getBytes());
bf.flush();
bf.close();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
}
BufferOutputStream是过滤流中的一种 用于将字节写到缓冲先 等缓冲区满才会写入到文件中
DataOutputStream将不同的java数据类型写入到流中 都转换成byte 并且从最高位开始写
import
java.io.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
class
StreamTest
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static void main(String[] args) throws Exception...{
FileOutputStream f1 = new FileOutputStream("1.rmvb");
BufferedOutputStream bf = new BufferedOutputStream(f1);
DataOutputStream df = new DataOutputStream(bf);
byte a1 = 1;
char a2 = 'a';
float a3 = 1.3f;
int a4 = 1;
df.writeByte(a1);
df.writeChar(a2);
df.writeFloat(a3);
df.writeInt(a4);
df.close();
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
这些数据都被换成了相应的字节数据
1 byte 1个字节 对应 01
a char 2 个字节 对应 00 61
1.3f float 4个字节 对应 3F A6 66 66
1 int 4个字节 对应 00 00 00 01
这个过滤的作用就很明显了
可以自己根据需要不断重组过滤流类来得到自己想要的功能的过滤流类 只要一个过滤流的构造以另一个过滤流为参数
打印流PrintStream
System里的out 就是一个打印流 有各种格式化的输出
另一个例子用来说明管道流的作用
import
java.io.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
class
Producer
extends
Thread
...
{
private PipedOutputStream pos;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public Producer(PipedOutputStream pos)...{
this.pos=pos;
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void run()...{
try
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
pos.write("Hello,RainyTooo!".getBytes());
pos.close();
}catch(Exception e)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
e.printStackTrace();
}
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
class
Consumer
extends
Thread
...
{
private PipedInputStream pis;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public Consumer(PipedInputStream pis)...{
this.pis=pis;
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void run()...{
try
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
byte[] byt = new byte[100];
int len = pis.read(byt);
System.out.println(new String(byt,0,len));
pis.close();
}catch(Exception e)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
e.printStackTrace();
}
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
PipedStreamTest
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static void main(String[] args)...{
PipedOutputStream pos = new PipedOutputStream(); //创建尚未连接到传送输入流的传送输出流
PipedInputStream pis = new PipedInputStream();
try
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
pos.connect(pis); //用管道的输出留连接输入流;
new Producer(pos).start(); //启动线程;
new Consumer(pis).start();
}catch(Exception e)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
e.printStackTrace();
}
}
}
管道流之间谁连接谁都可以的
ByteArrayOutputStream是一个把字节数组当作输出流的实现 具有缓冲区 可以在构造额达时候自己设定 其中有方便的方法得到字符串和输出到文件
主要有以下三个方便的方法
toString方法还有重载的
void | writeTo(OutputStream out) 将此字节数组输出流的全部内容写入到指定的输出流参数中,这与使用 out.write(buf, 0, count) 调用该输出流的 write 方法效果一样。 |
一个例子
import
java.io.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
ByteArrayTest
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String[] args)throws Exception
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
ByteArrayOutputStream bos=new ByteArrayOutputStream();
String s="This is a test";
byte[] buf=s.getBytes();
bos.write(buf);
System.out.println(bos.toString());
byte[] buf2= bos.toByteArray();
for (int i=0; i<buf.length; i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
System.out.print((char) buf2[i]);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
FileOutputStream f=new FileOutputStream("testByteArray.txt");
bos.writeTo(f);
}
}
SequenceInputStream(顺序输入流)
SequenceInputStream类允许连接多个InputStream流。SequenceInputStream的构造不同于任何其他的InputStream。SequenceInputStream构造函数要么使用一对InputStream,要么用InputStream的一个Enumeration,显示如下:
SequenceInputStream(InputStream first, InputStream second)
SequenceInputStream(Enumeration streamEnum)
操作上来说,该类满足读取完第一个InputStream后转去读取第二个流的读取要求。使用Enumeration的情况下,它将继续读取所有InputStream流直到最后一个被读完。
例子
输出两个文件内容
import
java.io.
*
;
import
java.util.
*
;
class
InputStreamEnumerator
implements
Enumeration
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
private Enumeration files;
public InputStreamEnumerator(Vector files)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
this.files = files.elements();
}
public boolean hasMoreElements()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return files.hasMoreElements();
}
public Object nextElement()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
try
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return new FileInputStream(files.nextElement().toString());
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (Exception e) ...{
return null;
}
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
class
SequenceInputStreamDemo
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String args[]) throws Exception
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
int c;
Vector files = new Vector();
files.addElement("StreamTest.java");
files.addElement("Test.java");
InputStreamEnumerator e = new InputStreamEnumerator(files);
InputStream input = new SequenceInputStream(e);
while ((c = input.read()) != -1)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
System.out.print((char) c);
}
input.close();
}
}
字符流
Reader和Write
两个抽象类 作用就是方便字符的 输入和输出 子类必须实现read和close方法
Reader的子类
BufferedReader CharArrayReader FilterReader InputStreamReader PipedReader StringReader
Writer的子类
BufferedWriter CharArrayWriter FilterWriter OutputStreamWriter PipedWriter StringWriter PrintWriter
其中InputStreamReader 的子类FileReader 和 OutputStreamWriter的 子类 FileWriter提供了对文件的直接操作字符的方式
RandomAccessFile(随机访问文件类)
RandomAccessFile 包装了一个随机访问的文件。它不是派生于InputStream 和OutputStream,而是实现定义了基本输入/输出方法的DataInput和DataOutput接口。 这个类同时具有读和写的方法 还有文件指针可以方便在制定位置读和写操作
提供了文件的随机存取的功能整合
RandomAccessFile
它是一个完全独立的class,拥有大量的原生函数,它和其他的IO有本质上的差异
,允许你在文件内自由的前后移动
seek()
的作用是指针
public RandomAccessFile(File file,
String mode)
throws FileNotFoundException创建从中读取和向其中写入(可选)的随机存取文件流,该文件由 File 参数指定。将创建一个新的 FileDescriptor 对象来表示此文件的连接。
mode 参数指定用以打开文件的访问模式。允许的值及其含意为:
值
含意
"r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。
"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
"rws" 打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到基础存储设备。
"rwd" 打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到基础存储设备。
有3种string的写入方法
writeByte(String s)没有读取的方法
writeChar(String s)
writeUTF(String s)可以记录字节的长度在前面用两个字节表示
在RandomAccessFile中
long getFilePointer()
返回此文件中的当前偏移量。
例子 :用RandomAccessFile类读写文件
import
java.io.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
RandomAccessFileTest
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String[] args)throws Exception
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
Student a1 = new Student(1,"wang",99.0);
Student a2 = new Student(2,"zhang",22.0);
Student a3 = new Student(3,"xiang",33.0);
RandomAccessFile raf = new RandomAccessFile("students.txt", "rw");
a1.writeStudents(raf);
a2.writeStudents(raf);
a3.writeStudents(raf);
Student s = new Student();
raf.seek(0); //将文件指针移到启始位置;
for(long i =0; i<raf.length();i=raf.getFilePointer()) //返回long型的指针偏移量
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
s.readStudents(raf);
System.out.println(s.num+": " + s.name+": " +s.scores);
}
raf.close();
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
class
Student
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int num;
String name;
double scores;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public Student()...{
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public Student(int num, String name, double scores)...{
this.num=num;
this.name=name;
this.scores=scores;
}
public void writeStudents(RandomAccessFile raf)throws IOException
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
raf.writeInt(num);
raf.writeUTF(name);
raf.writeDouble(scores);
}
public void readStudents(RandomAccessFile raf)throws IOException
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
num = raf.readInt();
name = raf.readUTF();
scores = raf.readDouble();
}
}
对象的序列化
将一个对象转化为字节流
以便保存和还原一个对象
对象序列化必须实现Serializable或者Externalizable接口
1 当一个对象序列化的时候只保存非静态的成员变量不能保存任何成员方法和静态的成员变量
2 如果一个对象的成员变量是一个对象,那么这个对象的数据也会被保存
3 如果一个可序列化的对象包含一个不可序列化的对象的引用,那么整个序列化的操作就将失败
声明为transient时可以继续序列化
例子:
import
java.io.
*
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
class
ObjectSerialTest
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String[] args) throws Exception
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
Employee e1=new Employee("zhangsan",25,3000.50);
Employee e2=new Employee("lisi",24,3200.40);
Employee e3=new Employee("wangwu",27,3800.55);
FileOutputStream fos=new FileOutputStream("employee.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(e1);
oos.writeObject(e2);
oos.writeObject(e3);
oos.close();
FileInputStream fis=new FileInputStream("employee.txt");
ObjectInputStream ois=new ObjectInputStream(fis);
Employee e;
for(int i=0;i<3;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
e=(Employee)ois.readObject();
System.out.println(e.name+":"+e.age+":"+e.salary);
}
ois.close();
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
class
Employee
implements
Serializable
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
String name;
int age;
double salary;
transient Thread t=new Thread();
public Employee(String name,int age,double salary)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
this.name=name;
this.age=age;
this.salary=salary;
}
private void writeObject(java.io.ObjectOutputStream oos) throws IOException
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
oos.writeInt(age);
oos.writeUTF(name);
System.out.println("Write Object");
}
private void readObject(java.io.ObjectInputStream ois) throws IOException
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
age=ois.readInt();
name=ois.readUTF();
System.out.println("Read Object");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}