有时我们需要将一个链表对象写入磁盘,需要时再从磁盘中读取。那么,如何将一个对象存入磁盘呢?
package com.nature.util
/**
* 字节编码器
* @author Administrator
*/
public class ByteByteEncoder{
/**
* short整数转换为2字节的byte数组
*/
public byte[] unsignedShortToByte2(int s) {
byte[] targets = new byte[2];
targets[0] = (byte) (s >> 8 & 0xFF);
targets[1] = (byte) (s & 0xFF);
return targets;
}
/**
* byte数组转换为无符号short整数
*/
public int byte2ToUnsignedShort(byte[] bytes) {
return byte2ToUnsignedShort(bytes, 0);
}
/**
* byte数组转换为无符号short整数
*/
public int byte2ToUnsignedShort(byte[] bytes, int off) {
int high = bytes[off];
int low = bytes[off + 1];
return (high << 8 & 0xFF00) | (low & 0xFF);
}
/**
* int整数转换为4字节的byte数组
*/
public byte[] intToByte4(Integer i){
byte[] targets = new byte[4];
targets[3] = (byte) (i & 0xFF);
targets[2] = (byte) (i >> 8 & 0xFF);
targets[1] = (byte) (i >> 16 & 0xFF);
targets[0] = (byte) (i >> 24 & 0xFF);
return targets;
}
/**
* byte数组转换为int整数
*/
public int byte4ToInt(byte[] bytes,int off){
int b0 = bytes[off] & 0xFF;
int b1 = bytes[off + 1] & 0xFF;
int b2 = bytes[off + 2] & 0xFF;
int b3 = bytes[off + 3] & 0xFF;
return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
}
/**
* long整数转换为8字节的byte数组
*/
public byte[] longToByte8(long lo) {
byte[] targets = new byte[8];
for (int i = 0; i < 8; i++) {
int offset = (targets.length - 1 - i) * 8;
targets[i] = (byte) ((lo >>> offset) & 0xFF);
}
return targets;
}
}
package com.nature.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import com.nature.po.Syslog;
/**
* 链表数据的磁盘读写
* @author Administrator
*/
public class WareHouse {
private String charSet; //字符集
/**
* 构造方法
*/
public WareHouse() {
this.charSet = "UTF8";
}
/**
* 写入磁盘
* @param pdpList 链表数据
* @param filePath 文件路径
*/
public void write(List
ByteByteEncoder byteByteEncoder = new ByteByteEncoder();
//文件
File filename = new File(filePath);
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(filename);
for(Syslog syslog : syslogList){
String sourceIp = syslog.getSourceIp(); //主机IP
String message = syslog.getMessage(); //内容
String totalStr = sourceIp+message; //汇总信息
//字符串 编码 字节数组
byte[] totalByte = totalStr.getBytes(charSet);//汇总信息字节数组
byte[] sourceIpByte = sourceIp.getBytes(charSet);
byte[] messageByte = message.getBytes(charSet);
//System.out.println(totalByte.length+"="+sourceIpByte.length+"+"+messageByte.length);
//字节数组长度 编码 字节数组
byte[] totalSize = byteByteEncoder.unsignedShortToByte2(totalByte.length);//汇总信息字节数组长度 编码
byte[] sourceIpSize = byteByteEncoder.unsignedShortToByte2(sourceIpByte.length);
byte[] messageSize = byteByteEncoder.unsignedShortToByte2(messageByte.length);
// 写入到文件中
fileOutputStream.write(totalSize); // 先写总长度
fileOutputStream.write(sourceIpSize); // 先写IP长度
fileOutputStream.write(messageSize); // 先写message长度
fileOutputStream.write(totalByte); // 再写信息内容
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 读取磁盘
* @param url 文件路径
* @return 链表数据
*/
public List
List
ByteByteEncoder byteByteEncoder = new ByteByteEncoder();
byte[] buf = new byte[2048];//当UDP数据包为1024时,存储需要更多。
boolean flag = true;
// 文件
File filename = new File(url);
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(filename);
while(flag){
//存放汇总信息总长度、IP长度、message长度
int[] sizeArr = new int[3];
for(int i=0;i<3;i++){
//读取2个字节并解码,获得数据长度
int num = fileInputStream.read(buf, 0, 2);
if(num != 2){ flag = false; break;}
sizeArr[i] = byteByteEncoder.byte2ToUnsignedShort(buf, 0);
}
//数据头部完整性校验,保证总长=IP长+内容长,保证总长不大于buf.length
if(!flag || sizeArr[0]!=(sizeArr[1]+sizeArr[2]) || sizeArr[0]>buf.length){ break;}
//数据内容完整性校验
int total = fileInputStream.read(buf, 0, sizeArr[0]); //java.lang.IndexOutOfBoundsException
if(sizeArr[0] != total){ break;}
//解码信息,还原对象
String sourceIp = new String(buf,0,sizeArr[1],charSet);
String message = new String(buf,sizeArr[1],sizeArr[2],charSet);
Syslog syslog = new Syslog();
syslog.setSourceIp(sourceIp); //完成IP还原
syslog.setMessage(message); //完成内容还原
syslogList.add(syslog);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return syslogList;
}
public static void main(String[] args){
List
String ip = "192.168.156.102";
String message = "<30>测试 123 ";
Syslog syslog = new Syslog();
syslog.setSourceIp(ip);
syslog.setMessage(message);
ss.add(syslog);
ss.add(syslog);
ss.add(syslog);
ss.add(syslog);
WareHouse wareHouse = new WareHouse();
try {
wareHouse.write(ss,"d:/bbbb");
List
for(Syslog pdp : pdpList) {
System.out.println("got:"+pdp.getSourceIp()+"\t"+pdp.getMessage());
}
}catch(Exception e) {
e.printStackTrace();
}
}
}