如何实现链表的磁盘读写

有时我们需要将一个链表对象写入磁盘,需要时再从磁盘中读取。那么,如何将一个对象存入磁盘呢?

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 syslogList,String filePath){

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 read(String url){

List syslogList = new LinkedList();

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 ss=new LinkedList();

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 pdpList = wareHouse.read("d:/bbbb");

for(Syslog pdp : pdpList) {

System.out.println("got:"+pdp.getSourceIp()+"\t"+pdp.getMessage());

}

}catch(Exception e) {

e.printStackTrace();

}

}

}

你可能感兴趣的:(Java开发)