对象串行化-随心所欲

       前一段时间,做了一个对象串行化的实例,今天又写了一个实例,与之前的不同的是,这次串行化不是一个绝对的串行化,而是一个将对象和对象包含的附件(文件)混杂一并写入到一个文件,较之前面的实例来看,这个实例的实用性更强,可以在写入对象和附件后,单独读出对象和单独读出某个附件。就像在蓝杰公司写山寨QQ程序,有些时候需要自定义读写协议。

 

HeadObjectAttachment1Attachment2Attachment3Attachment4... ...Attachment n
longbyte[]byte[]byte[]byte[]byte[]byte[]

 

注:Head存储了Object串行化所需要的字节数组长度。

 

Task.java

package cn.hunnu.test1;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.List;

/**
 * Task 
 * @author 肖波
 *
 */
public class Task implements Serializable
{
	private static final long serialVersionUID = 1L;
	private String taskName;
	private Timestamp createOn;
	private String content;
	private Timestamp lastModifiedOn;
	private List<Attachment> attachmentList;
	
	public Task()
	{
		
	}
	public Task(String taskName,Timestamp createOn,String content,Timestamp lastModifiedOn)
	{
		this.taskName = taskName;
		this.createOn = createOn;
		this.content = content;
		this.lastModifiedOn = lastModifiedOn;
	}
	public void info()
	{
		System.out.println("Task Name:"+taskName);
		System.out.println("Created On:"+createOn);
		System.out.println("Last Modified On:"+lastModifiedOn);
		System.out.println("Content:"+content);
		System.out.println("Attachments:");
		if(attachmentList!=null&&attachmentList.size()>0)
		{
			int size = attachmentList.size();
			for(int i = 0;i<size;i++)
			{
				System.out.print("att"+i+":");
				System.out.println(attachmentList.get(i));
			}
		}
		
	}
	public String getTaskName() {
		return taskName;
	}
	public void setTaskName(String taskName) {
		this.taskName = taskName;
	}
	public Timestamp getCreateOn() {
		return createOn;
	}
	public void setCreateOn(Timestamp createOn) {
		this.createOn = createOn;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public Timestamp getLastModifiedOn() {
		return lastModifiedOn;
	}
	public void setLastModifiedOn(Timestamp lastModifiedOn) {
		this.lastModifiedOn = lastModifiedOn;
	}
	public List<Attachment> getAttachmentList() {
		return attachmentList;
	}
	public void setAttachmentList(List<Attachment> attachmentList) {
		this.attachmentList = attachmentList;
	}
	
}
 

Attachment.java

package cn.hunnu.test1;

import java.io.File;
import java.io.Serializable;

public class Attachment implements Serializable
{
	private static final long serialVersionUID = 1L;
	private File file;
	private String fileName;
	private String storageID;
	private long size;
	
	public Attachment(){}
	public Attachment(File file,String fileName,String storageID,long size)
	{
		this.file = file;
		this.fileName = fileName;
		this.storageID = storageID;
		this.size = size;
	}
	public File getFile() {
		return file;
	}
	public void setFile(File file) {
		this.file = file;
	}
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public String getStorageID() {
		return storageID;
	}
	public void setStorageID(String storageID) {
		this.storageID = storageID;
	}
	public long getSize() {
		return size;
	}
	public void setSize(long size) {
		this.size = size;
	}
	public String toString()
	{
		StringBuffer sb = new StringBuffer();
		sb.append("{File Name:\"");
		sb.append(fileName);
		sb.append("\",Size:\"");
		sb.append(size);
		sb.append("\",StorageID:\"");
		sb.append(storageID);
		sb.append("\"}");
		return sb.toString();
	}
}
 

测试类:

package cn.hunnu.test1;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.RandomAccessFile;
import java.util.List;

public class Main 
{
	public static void main(String args[])
	{
		Task task = new Task("Serializable Task",new Timestamp(new Date().getTime()),
                             "Content of Task",new Timestamp(new Date().getTime()));
		List<Attachment> attList = new ArrayList<Attachment>();
		File f1 = new File("D:\\Documents\\Document for CIM\\Task_Management_Overview_V02.ppt");//1168KB
		File f2 = new File("D:\\Documents\\Document for CIM\\2010 Direct Client Satisfaction Surveys.zip");//405KB
		File f3 = new File("D:\\Documents\\Document for CIM\\CIM_BottomPanel.pdf");//895KB
		Attachment att1 = new Attachment();
			att1.setFile(f1);
			att1.setFileName("Task_Management_Overview_V02.ppt");
			att1.setStorageID("0001");
			att1.setSize(f1.length());
		Attachment att2 = new Attachment();
			att2.setFile(f2);
			att2.setFileName("2010 Direct Client Satisfaction Surveys.zip");
			att2.setStorageID("0002");
			att2.setSize(f2.length());
		Attachment att3 = new Attachment();
			att3.setFile(f3);
			att3.setFileName("CIM_BottomPanel.pdf");
			att3.setStorageID("0003");
			att3.setSize(f3.length());
		attList.add(att1);
		attList.add(att2);
		attList.add(att3);
		task.setAttachmentList(attList);
		
		//write to file
		write(task);
		
		//read from file
		Task retrievedTask1 = readTaskObject();
		Task retrievedTask2 = readTaskAll();
		retrievedTask1.info();
		retrievedTask2.info();
		
		//get assigned file
		getFile("Task_Management_Overview_V02.ppt","0001");
		getFile("2010 Direct Client Satisfaction Surveys.zip","0002");
		getFile("CIM_BottomPanel.pdf","0003");
	}
	
	public static void write(Task task)
	{
		try{
			//create a memory output stream.
			ByteArrayOutputStream bops = new ByteArrayOutputStream();
			ObjectOutputStream fout = new ObjectOutputStream(bops);
			fout.writeObject(task);
			fout.flush();
			fout.close();//close ObjectOutputStream and close ByteArrayOutputStream
			
			//get the length of serialized Object
			byte[] objectByteArray = bops.toByteArray();
			long lengthOfObject = objectByteArray.length;
			
			//write to file
			File targetFile = new File("D:/object1.txt");
			FileOutputStream fis = new FileOutputStream(targetFile);
			BufferedOutputStream bout = new BufferedOutputStream(fis);
			//1,write Object length
			DataOutputStream dos = new DataOutputStream(fis);
			dos.writeLong(lengthOfObject);//write the Head.
			dos.flush();
			//2,write Object
			bout.write(objectByteArray);//write the object.
			
			//3,write attachment files
			List<Attachment> attList = task.getAttachmentList();
			if(attList!=null&&attList.size()>0)
			{
				BufferedInputStream bis;
				for(Attachment att : attList)
				{
					File file = att.getFile();
					if(file!=null)
					{
						bis = new BufferedInputStream(new FileInputStream(file));
						byte[] per = new byte[1024];//1KB
						long count = att.getSize()/per.length;
						long residueBytes = att.getSize()%per.length;
						for(int j = 0;j<count;j++)
						{
							bis.read(per);
							bout.write(per);
						}
						if(residueBytes>0){
							byte[] left = new byte[(int)residueBytes];
							bis.read(left);
							bout.write(left);
						}
						bis.close();
					}
					else
					{
						bout.write(new byte[0]);
					}
				}
			}
			bout.flush();
			bout.close();
			
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static Task readTaskObject()
	{
		Task task = null;
		try
		{
			File objectFile = new File("D:/object1.txt");
			FileInputStream fis = new FileInputStream(objectFile);
			DataInputStream dis = new DataInputStream(fis);
			//read head:length of Object
			long objectLength = dis.readLong();
			
			//read object
			byte[] objectByteArray = new byte[(int) objectLength];
			dis.read(objectByteArray);
			ByteArrayInputStream bis = new ByteArrayInputStream(objectByteArray);
			ObjectInputStream ois = new ObjectInputStream(bis);
			task = (Task)ois.readObject();
			ois.close();
			dis.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return task;
	}
	
	public static Task readTaskAll()
	{
		Task task = null;
		try
		{
			File objectFile = new File("D:/object1.txt");
			FileInputStream fis = new FileInputStream(objectFile);
			DataInputStream dis = new DataInputStream(fis);
			//read head:length of Object
			long objectLength = dis.readLong();
			
			//read object
			byte[] objectByteArray = new byte[(int) objectLength];
			dis.read(objectByteArray);
			ByteArrayInputStream bis = new ByteArrayInputStream(objectByteArray);
			ObjectInputStream ois = new ObjectInputStream(bis);
			task = (Task)ois.readObject();
			ois.close();
			
			//read attachment files
			List<Attachment> attachList = task.getAttachmentList();
			if(attachList!=null&&attachList.size()>0)
			{
				String tempDir = "D:/tmp1/";
//				FileOutputStream fos;
				BufferedOutputStream bout;
				for(Attachment att : attachList)
				{
					String fileName = att.getFileName();
					File tempFile = new File(tempDir+fileName);
					if(!tempFile.exists()){
						tempFile.createNewFile();
					}
					long size = att.getSize();
//					fos = new FileOutputStream(tempFile);
					bout = new BufferedOutputStream(new FileOutputStream(tempFile));
					//for cycle
					byte[] per = new byte[1024];//1KB
					long count = size/per.length;
					long residueBytes = size%per.length;
					for(int j = 0;j<count;j++)
					{
						dis.read(per);
						bout.write(per);
					}
					if(residueBytes>0){
						byte[] left = new byte[(int)residueBytes];
						//in.read(left);
						//fos.write(left);
						dis.read(left);
						bout.write(left);
					}
					//for cycle
					
					bout.flush();
					bout.close();
				}
			}
			dis.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return task;
	}
	/**
	 * the file which get from stream will be saved at the path "D:\\downloadFile"
	 * @param fileName
	 * @param storageID
	 */
	public static void getFile(String fileName ,String storageID)
	{
		try
		{
			File objectFile = new File("D:/object1.txt");
			FileInputStream fis = new FileInputStream(objectFile);
			DataInputStream dis = new DataInputStream(fis);
			//read head:length of Object
			long objectLength = dis.readLong();
			
			//read object
			byte[] objectByteArray = new byte[(int) objectLength];
			dis.read(objectByteArray);
			ByteArrayInputStream bis = new ByteArrayInputStream(objectByteArray);
			ObjectInputStream ois = new ObjectInputStream(bis);
			Task task = (Task)ois.readObject();
			ois.close();
			dis.close();
			//read attachment files
			int off = (int) (objectLength+8);
			List<Attachment> attachList = task.getAttachmentList();
			if(attachList!=null&&attachList.size()>0)
			{
				String downloadDir = "D:/downloadFile/";
				BufferedOutputStream bout;
				RandomAccessFile raf = new RandomAccessFile(objectFile,"r");
				for(Attachment att : attachList)
				{
					if(!storageID.equals(att.getStorageID()))
					{
						// move offset
						off+=att.getSize();
					}
					else
					{
						raf.seek(off);
						//String file_name = att.getFileName();
						File tempFile = new File(downloadDir+fileName);
						if(!tempFile.exists()){
							tempFile.createNewFile();
						}
						long size = att.getSize();
						bout = new BufferedOutputStream(new FileOutputStream(tempFile));
						//for cycle
						int per_r_length = 1024;//1KB per read
						byte[] per = new byte[per_r_length];//1KB
						int count = (int) (size/per_r_length);
						int residueBytes = (int) (size%per_r_length);
						for(int i = 0;i<count;i++)
						{
							raf.read(per);
							bout.write(per);
							per = new byte[per_r_length];
						}
						if(residueBytes>0){
							byte[] left = new byte[(int)residueBytes];
							raf.read(left);
							bout.write(left);
						}
						//for cycle
						
						bout.flush();
						bout.close();
						break;
					}
				}
			}
			dis.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}
 

 

注意:Task类中的serialVersionUID 属性非常重要,用于标识串行化对象的版本,可以做向前兼容和向后兼容。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值