0
点赞
收藏
分享

微信扫一扫

Java序列化和NIO

芝婵 2022-02-05 阅读 53

创建对象的四种方式

  • New 对象
    开辟内存空间,在堆中存放
  • 克隆 拷贝创建对象
  • 反序列化
    把字节序列恢复为原来的Java对象
  • 反射

序列化与反序列化

序列化:是一个Java对象作一下“变换”,变成字节序列。这样一来方便持久化存储到磁盘,避免程序运行结束后对象就从内存里消失,另外变换成字节序列也更便于网络运输和传播。

反序列化: 把字节序列恢复为原来的Java对象。

实现序列化的接口:Serializable

Serializable是一个标记性接口,没有实现任何内容,只是告诉JVM当前对象需要序列化。
(Cloneable接口也是一个标记性接口,没有任何内容,只是告诉JVM该对象需要克隆)

SerialVersionUID是序列化前后唯一的标识符,如果没有人为定义过SerialVersionUID,那么编译器会自动声明一个。一般不需要人为处理。

  • 注:
    static修饰的不会被序列化
    transient修饰的不会被序列化

Demo

Car.java

package com.wdy.stream;
import java.io.Serializable;
public class Car implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L; //版本信息,编译器自动声明。一般不需要人为修改
	private int id;
	private String brand;
	private String color;
	private double price;

	public Car()  {

	}

	public Car (int id, String brand, String color, double price) {
		this.id = id;
		this.brand = brand;
		this.color = color;
		this.price = price;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Car [id=" + id + ", brand=" + brand + ", color=" + color + ", price=" + price + "]";
	}
}

输出流 写入Car对象的属性

package com.wdy.stream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/*
 * 输出流 写入Car对象的属性
 */
public class ObjectOutputStreamDemo {
	public static void main(String[] args) throws Exception {
		
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:\\car.dat")); //创建输入流对象  字节流对象
		Car c = new Car(1, "bmw", "黑色", 1200000.00);
		out.writeObject(c);//写入属性
		out.close();
		
		
	}
}

执行结果:
在这里插入图片描述

package com.wdy.stream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

/*
 * 输出流  把文件中的内容读出
 */
public class ObjectInputStreamDemo {
public static void main(String[] args) throws Exception {
		
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:\\car.dat"));
		
		Car  car = (Car) in.readObject();//.readObject() 读取对象的方法   读到的对象是Car对象 。强转
		
		System.out.println(car);

	}
}

执行结果:
在这里插入图片描述

NIO

java.nio全称java non-blocking 10- (实际上是new io),是指JDK 1.4及以上版本里提供的新api (New IO) ,为所有的原始类型(boolean类型除外):提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络。

NIO的组成

  • Channel (通道)
    通道表示打开到IO设备(例如:文件、套接字)的连接。若需要使用NIO系统,需要获取用于连接IO设备的通道以及用于容纳数据的缓冲区。然后操作缓冲区,对教据进行处理。
    Channel (通道)比IO中的Stream(字符流)更加高效, Channel 可以异步双向传输,但必须和buffer一起使用。

  • Buffer(缓存区)
    缓冲区本质上是一块可以写入数据, 然后可以从中读
    取教据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法, 用来方便的访问该块内存。

  • Selector
    允许单线程处理多个Channel ,如果你的应用打开了多个连
    接(通道),但每个连接的流量都很低,使用Selector方法就会很方
    便。
    Selector可以检测多个NIO Channel,看读或者写事件是否就绪。
    多个Chanel以事件的方式可以注册到同一个Seletor,从而使用一个线程处理多个请求成为可能。

Demo

nio和普通的输入输出流相比,可以同时读和写,实现非阻塞同步 。普通的流在执行读(写)任务就会阻塞写(读)线程。

package com.wdy.stream;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class NIODemo {
	public static void main(String[] args) throws Exception {
		String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
		System.out.println(path);
		path =path.substring(0, path.length()-4);
		System.out.println(path);
		String fileName = path+"src/io/file/FileDemo02.java";
		
		RandomAccessFile raf = new RandomAccessFile(fileName, "rw");//创建一个NIO读取的对象 “rw”代表可读可写
		
		FileChannel inChannel = raf.getChannel(); //开辟通道 ,开辟了通道(nio)和普通的输入输出流相比,可以同时读和写,非阻塞同步  。普通的流在执行读(写)任务就会阻塞写(读)线程
		
		ByteBuffer buffer = ByteBuffer.allocate(64);//开辟缓存空间。大小根据情况确认
		
		int n = 0;
		
		while((n=inChannel.read(buffer))!=-1) { //通过通道读取缓存中的内容
			buffer.flip();//移动到缓存的第一个位置
			while(buffer.hasRemaining()) {//判断缓存是否有数据
				System.out.print((char)buffer.get()); //按字节读。强转为char
			}
			buffer.clear();
		}		
		raf.close();	
	}
}

在这里插入图片描述
在这里插入图片描述

举报

相关推荐

0 条评论