【大数据开发】Java语言基础——对象流、RandomAccessFile、内存流、数据流与解码day19

一、ObjectOutputStream和ObjectInputStream(重点)

(1)创建对象:序列化

ObjectOutputStream有两种构造方法
在这里插入图片描述
知道了使用构造方法创建对象,那么怎么写入对象呢?
用下面的方法实现,将对象存储起来,实现持久化(程序运行时才存在对象----位于堆内存中,JVM退出时对象被销毁)
在这里插入图片描述
要序列化的某些对象不实现java.io.Serializable接口会产生NotSerializableException异常,因此必须要实现Serializable接口。一个类只有实现了Serializable接口才能实现序列化。

(2)读取对象:反序列化-----依据所属类的字节码xxx.class文件

知道了怎么写入对象,下面来说说怎么读取对象
首先创建根据构造方法对象
在这里插入图片描述
用下面的方法读取对象-----反序列化
在这里插入图片描述
在这里插入图片描述
应当注意的是Object readObject() 要抛出两个异常

(3)序列化和反序列化代码实现

import java.io.*;
class Person  implements Serializable //实现了该接口的类的对象才能持久化  NotSerializableException: Person
{
	public static final long serialVersionUID = 42L; 

	public transient String name;  //transient:瞬态的成员不参与序列化   //3832552154946523251
	private int age;

	Person(){}

	Person(String name,int age)
	{
		this.name=name;
		this.age=age;
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}
class Demo1 
{
	public static void main(String[] args) throws IOException,ClassNotFoundException
	{
		// ObjectOutputStream  ObjectInputStream
         writeObj();
		 
		 readObj();
	}

	//读取对象:反序列化---依据所属类的字节码Person.class
	public static void readObj()throws IOException,ClassNotFoundException
	{
		ObjectInputStream objin=new ObjectInputStream(new FileInputStream("object.txt"));
		//Object readObject() 
		Person ren =(Person)objin.readObject();

		System.out.println(ren.getName()+","+ren.getAge());
		objin.close();
	}

    //对象实现存储:持久化(序列化)
	public static void writeObj()throws IOException
	{
		ObjectOutputStream objout=new ObjectOutputStream(new FileOutputStream("object.txt"));//向文件中写入对象

		//void writeObject(Object obj) 
		objout.writeObject(new Person("李四",20));//Person.class  6353954888121467304-->Person.class

	    objout.close();
	}

}

若将该该文件的类Person类修改再重新编译,readObject()则会找不到Person.class文件,抛出如下异常:
在这里插入图片描述
原因在java.io.Serializable有详细说明:大概意思是每个类都会产生一个UID,而修改了类则该类的UID也会发生改变
在这里插入图片描述
根据API说明,我们也可以自己指定UID

static final long serialVersionUID = 42L  //Long类型,后面数字可以自己指定

自己指定了UID后再修改类后,同样readObject()仍然可以找到该类,充分说明它是根据类的UID找到的

transient:瞬态 transient修饰的成员不参与序列化
问题:为什么药序列化?
实现对象的持久化或网络传输

二、RandomAccessFile

RandomAccessFile是随机访问流类,只能访问文件,内部既有字节输入流,也有字节输出流。该类内有一个数组,使用指针实现随机访问(下标从0开始)。
准备知识:
(1)一个中文占2个字节,一个int型变量占4个字节
(2)RandomAccessFile的三个read()方法和InputStream()的三个read()方法完全一样
(3)RandomAccessFile的三个write()方法和InputStream()的三个write()方法完全一样
此外RandomAccessFile还包含了一系列的readXXX()和writeXXX()方法来完成输入输出

(1)先来看看构造方法

在这里插入图片描述
mode可以是"r",“rw”,“rws”,或 “rwd” (read、write缩写)
默认指针是指向了文件开头,那怎么获取文件的指针指到哪里了呢?
查看API有下面的方法 ---- getFilePointer()
在这里插入图片描述
那要修改指针的位置怎么办?------ seek()
在这里插入图片描述
注意应当使用String的构造方法对byte进行解码
在这里插入图片描述

(2)使用RandomAccessFile的示例代码

import java.io.*;
class Demo2 
{
	public static void main(String[] args)throws IOException,FileNotFoundException 
	{
		 writeData();
		 readData();
	}
	public static void readData()throws IOException,FileNotFoundException
	{
		RandomAccessFile random=new RandomAccessFile("random.txt","r");

        //默认从文件开头开始读数据
        byte[] arr=new byte[4];
        int num = random.read(arr);
        
		int age=random.readInt();
		System.out.println(new String(arr,0,num)+","+age);

        random.seek(16);

		num = random.read(arr);
		age=random.readInt();
		System.out.println(new String(arr,0,num)+","+age);
         
	}

    public static void writeData()throws IOException,FileNotFoundException
	{
		RandomAccessFile random=new RandomAccessFile("random.txt","rw");

		//默认指针指向文件开头
		random.write("刘能".getBytes());
		random.writeInt(58);

		//long getFilePointer()  
		long point = random.getFilePointer();
		System.out.println(point);//8

		random.seek(16);//设置指针的位置

		random.write("赵四".getBytes());
		random.writeInt(50);

		point = random.getFilePointer();
		System.out.println(point);//
	}
}

三、内存流

ByteArrayInputStream ----- 向字节数组中写数据(字节数组在内存中)
ByteArrayOutputStream ----- 从字节数组中读数据(字节数组在内存中)

(1)ByteArrayInputStream和ByteArrayOutputStream的构造方法

在这里插入图片描述
在这里插入图片描述
ByteArrayOutputStream的构造方法里面是空参的,说明ByteArrayOutputStream内部有一个字节数组,那么怎么得到ByteArrayOutputStream内部数组中的数据呢? ----- byte[] toByteArray()
在这里插入图片描述

(2)ByteArrayInputStream和ByteArrayOutputStream示例代码

import java.io.*;
class Demo3 
{
	public static void main(String[] args)throws IOException 
	{
		//ByteArrayInputStream(byte[] buf) 

		ByteArrayInputStream bis = new ByteArrayInputStream("wiksdhfkjsjhdfksjdhf".getBytes());

		ByteArrayOutputStream bos=new ByteArrayOutputStream();//其内部有一个字节数组

		byte[] arr=new byte[1024];
		int num=0;

		while((num=bis.read(arr))!=-1)
		{
			bos.write(arr,0,num);
		}

        //得到ByteArrayOutputStream内部数组中的数据    byte[] toByteArray()  
        byte[] b = bos.toByteArray();

		System.out.println(new String(b));
	}
}


四、数据流

DataOutputStream
DataInputStream

(1)DataOutputStream构造方法

只有一个
在这里插入图片描述

(2)DataInputStream 构造方法

只有一个
在这里插入图片描述

(3)使用方法(查看API)

DataOutputStream和DataInputStream的方法是对应的,读的顺序必须和写入的顺序保持一致

(4)示例代码

import java.io.*;
class Demo4 
{
	public static void main(String[] args)throws IOException  
	{
		 write();
		 read();
		
	}
	public static void read()throws IOException  
	{
		DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
		//读的顺序必须和写入的顺序一致
		System.out.println(dis.readDouble());
		System.out.println(dis.readBoolean());
		System.out.println(dis.readLong());

		dis.close();
	}

	public static void write()throws IOException  
	{
		 DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));

		 dos.writeDouble(88);
		 dos.writeBoolean(false);
		 dos.writeLong(66l);

		 dos.close();
       
	}

}

五、转换流与解码

OutputStreamWriter
InputStreamReader

(1)OutputStreamWriter构造方法

在这里插入图片描述
因此使用转换流可以设置编码
可以自己指定编码,若不指定则编码默认为gbk

(2)InputStreamReader构造方法

在这里插入图片描述
注意:写入的时候指定的是什么编码,则读取的时候也应当使用相同的编码,否则会产生乱码。

(3)使用OutputStreamWriter、InputStreamReader示例代码

import java.io.*;
class Demo5 
{
	public static void main(String[] args)throws IOException 
	{
		//System.out.println("Hello World!");
		//write();
		read();
	}
	public static void read()throws IOException
	{
		InputStreamReader isr=new InputStreamReader(new FileInputStream("gbk.txt"),"UTF-8");

		char[] arr=new char[10];
		int num = isr.read(arr);

		System.out.println(new String(arr,0,num));
	}

    //使用转换流设置编码
	public static void write()throws IOException 
	{
		OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");

		osw.write("你好");

		osw.close();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值