Java基础 IO流的使用

对象流的使用方式及说明

1.什么是java序列化,如何实现java序列化?

答:序列化就是一种用来处理对象流的机制,所谓的对象流也就是将对象的内容进行流化。

可以对流化后的对象进行读写操作,也可将流化后的对象传输与网络之间。序列化为了解决对对象读写时引发的问题。

序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有实现的方法,implements Serlalizable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象离得writeObject(Object obj)方法就可以将参数为obj的对象写出(即为保存状态),要恢复则用输入流。


2.使用处理流的优势有哪些?,如何识别所使用的流是处理流还是节点流?

答案:优势:对开发人员来说,使用处理流进行输入/输出操作更简单,使用处理流的执行效率更高。

判别:处理流的构造器的参数不是一个物理节点,而是已经存在的流。而节点流都是直接以物理io及节点作为构造器参数的。


3.对象流介绍

1.ObjectInputStream和ObjectOutputStream

用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把java中的对象写入到数据源中,也能把对象从数据源中还原回来。

2.序列化:用ObjectOutputStream类**保存**基本类型数据或对象的机制

3.反序列化:用ObjectInputStream类读取基本类型数据或对象的机制

4.ObjectOutputStream和ObjectInputStream不能序列化***static*transient**修饰的成员变量

4.对象的序列化

1.**对象序列化机制**允许把内存中的java对象转换成平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点.//当其他程序获取了这种二进制流,就可以恢复原来的java对象

2.序列化的好处在于可将任何实现了Serializeble接口的对象转化了字节数据,使其在保存和传输时可被还原

3.序列化是RMI(Remote Method Invoke -远程方法调用)过程的参数和返回值都必须实现的地址,而RMI是JavaEE的基础.因此序列化机制是JavaEE平台的基础

4.如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一,否则会抛出NotSerializableException异常

Serializable

​ Externalizable

5.凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量

1.private static final long serialVersionUID;

2.serialVersionUID用来表明类的不同版本间的兼容性,简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。

3.如果类没有显示定义这个静态变量,他的值是java运行时环境根据类的内部细节自动生成的。***若类的实例变量做了修改,serialVersionUID可能发生变化。***故建议,显示声明.

简单来说,Java的序列化机制是听过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地实体类的serialVersionUID进行比较,如果相同相同,就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常(InvalidCastException)

使用对象流序列化对象

1.若某个类实现了 Serializable 接口,该类的对象就是可序列化的:

​ 1.创建一个ObjectOutputStream

​ 2.调用ObjectOutputStream对象的writeObject(对象)方法输出可序列化对象

​ 3.注意写一次,操作flush()一次;

2、反序列化

1.创建一个ObjectInputStream

​ 2.调用readObject()方法读取流中的对象

3.强调:如果某个类的属性不是基本数据类型或String 类型,而是另一个引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的Fieid的类也不能序列化

//序列化:将对象写入到磁盘或者进行网络传输。

//要求对象必须实现序列化

ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("data.txt"));
Person  p=new Person("韩梅梅",18,"中华大街"new Pet());
oos.writeObject(p);
oos.flush();
oss.close();

//反序列化:将磁盘中的对象数据源读出。

ObjectInputStream ois=new ObjectInputStream(new FileInputStream("data.txt"));
Person p1=(Person)ois.readObject();
System.out.println(p1.toString());
ois.close();
谈谈你对java.io.Serializable接口的理解,我们知道他用于序列化是控方法接口,还有其他认识吗?

1.实现了Serializable接口的对象,可将他们转换为一系列字节,并可在以后完全恢复回原来的样子.这一过程亦可通过网络进行。这意味着序列化机制自动补偿系统间的差异。换句话说,可以先在Windows机器上创建一个对象,对其序列化,然后通过网络发给一台unix机器,然后在那里建一个对象,对其序列化,然后通过网络发给一台Unix机器,然后在那里准确无误的重新"装配"。不必关心数据在不同机器上如何表示,也不必关心字节的顺序或者其他任何细节。

2.由于大部分座位参数的类入String、Integer等都实现了java.io.Serializable的接口,也可以利用多态的性质,作为参数使接口更灵活。

随机存储文件流
RandomAccessFile类

1.RandomAccessFile声明在java.io包下,但直接继承与java.lang.Object类。并且它实现了DataInput、DataOutput两个接口,也就意味着这个类既可以读也可以写。

2.RandomAccessFile类支持“随机访问”的方式,程序可以直接跳到文件的任意地方来读、写文件

​ 1.支持只访问文件的部分内容

​ 2.可以向已存在的文件后追加内容

3.***RandomAccessFile***对象包含一个记录指针,用以标识当前度写处的位置。

​ RandomAccessFile类对象可以自由移动记录指针:

​ **long getFilePointer()😗*获取指针的当前位置

​ **void seek(long pos)😗*将文件记录指正定位在pos位置上

RandomAccessFile类

1.构造器

​ public RandomAccessFile(File file,String mode)

​ public RandomAccessFile(String name,String mode)

2.创建RandomAccessFile类实例需要制定一个mode参数,该参数指定RandomAccessFile的访问模式:

​ 1.r:以只读方式打开

​ 2.rw:打开以便读取和写入

​ 3.rwd:打开以便读取和写入;同步文件内容的更新

​ 4.rws:打开以便读取和写入;

3.如果模式为只读r。则不会创建文件,而是会去读取一个已经存在的文件,如果读取的文件不存在则会出现异常。如果模式为rw读写,如果文件不存在则会去创建文件,如果存在则不会创建

我们可以用RandomAccessFile这个类,来实现一个多线程断点下载的功能,用过下载工具的人都知道,下载前都会建立两个临时文件,一个是与被下载文件大小相同的空文件,另一个是记录文件指针的位置文件,每次暂停的时候,都会保存上一次的指针,然后断点下载的时候,会记录从上一次的机房下载,从而实现断点下载或上传功能。

读取文件内容
RandomAccessFile raf=new RandomAccessFile(“test.txt”,"'rw');

rea.seek(5);

byte [] b=new byte[1024];


int off=0;

int len=5;

raf.read(b,off,len);

String str=new String(b,0,len);

System.out.println(str);

raf.close();
写入文件内容
RandomAccessFile raf=new RandomAccessFile("text.txt","rw");
raf.seek(5);
//先读出来
String temp=raf.readLine();

raf.write("xyz",getBytes());
raf.write(temp.getBytes());

raf.close();
写入文件内容
RandomAccessFile raf1=new RandomAccessFile(“hello.txt”,"rw";
raf1.seek(5);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
byte[] buffer=new byte[10];
int len;
while((len=raf1.read(buffer))!=-1){
    baos.write(buffer,0,len);
}
raf1.seek(5);
raf1.write("xyz".getBytes());
raf1.write(baos.toString().getBytes());
baos.close();
raf1.close();
流的基本小结

1.流是用来处理数据的。

2.处理数据时,一定要先明确数据源,与数据目的地

​ 1.数据源可以是文件,可以是键盘。

​ 2.数据目的地可以是文件、显示器或其他设备。

3.而流只是在帮助数据进行传输,并对传输的数据进行处理,比如过滤处理、转换处理等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值