/*
* @(#)MemoryMappedFile.java 1.00 2007-12-5
*
* Copyright 2007 BCINFO. All Rights Reserved.
* Programmer: Xuym.
*/
package com.bci.commons.mmf;
// import org.apache.log4j.Logger;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.bci.commons.mmf.cell.AbstractCell;
import com.bci.commons.util.IOUtils;
/**
* 共享内存读写类,对java.nio.MappedByteBuffer封装,提供简单的读写操作。
* 采用java.util.concurrent.locks.Lock加锁机制支持多线程安全。
*
* @author xuym
* @version 1.00, 2007-12-5
* @since JDK 1.5
* @see java.nio.MappedByteBuffer
*/
public abstract class MemoryMappedFile {
/**
* Logger for this class
*/
// private static final Logger logger =
// Logger.getLogger(SharedMemory.class);
protected MappedByteBuffer mapBuf = null;
protected String file = null;
protected long capacity;
protected ReadWriteLock lock = new ReentrantReadWriteLock();
protected Lock readLock = lock.readLock();
protected Lock writeLock = lock.writeLock();
/**
* Load the map file into memory.
*
* @param file
* The file name to be load.
* @param size
* The file's size or the max map size.
* @throws MemoryMapException
* If some exception occurs when loading the file
* @throws MemoryNotMappedException
* If the file not mapped into memory
* @throws MemoryReadException
* If some exception occurs when reading the memory.
*/
public void load(String file, int size) throws MemoryMapException,
MemoryNotMappedException, MemoryReadException {
this.file = file;
this.capacity = size;
// logger.debug("loading the file " + this.file + " into memory...");
try {
RandomAccessFile RAFile = new RandomAccessFile(this.file, "rw");
FileChannel fc = RAFile.getChannel();
mapBuf = fc.map(FileChannel.MapMode.READ_WRITE, 0, size);
mapBuf.load();
fc.close();
RAFile.close();
} catch (FileNotFoundException e) {
throw new MemoryMapException(e);
} catch (IOException e) {
throw new MemoryMapException(e);
}
}
/**
* 在内存映象的指定位置写入对象
*
* @param desPos
* The dest position of the memory map.
* @param message
* The message object.
* @return The boolean value if successed.
* @see com.bci.commons.mmf.cell.AbstractCell
* @throws MemoryNotMappedException
* If the file not mapped into memory
* @throws MemoryWriteException
* If some exception occurs when write the object.
*/
public MemoryMappedFile write(int desPos, AbstractCell message)
throws MemoryNotMappedException, MemoryWriteException {
if (message == null)
throw new MemoryWriteException("The input object is null.");
return write(desPos, message.getBytes());
}
/**
* 在内存映象的指定位置写入字节数组
*
* @param desPos
* The dest position of the memory map.
* @param buf
* The byte array to be writen.
* @return The boolean value if successed.
* @throws MemoryNotMappedException
* If the file not mapped into memory
* @throws MemoryWriteException
* If some exception occurs when write the object.
*/
public MemoryMappedFile write(int desPos, byte[] buf)
throws MemoryNotMappedException, MemoryWriteException {
if (buf == null)
throw new MemoryWriteException("The input data is null.");
return write(desPos, buf, 0, buf.length);
}
/**
* 在内存映象的指定位置写入字节数组
*
* @param desPos
* The dest position of the memory map.
* @param buf
* The byte array to be writen.
* @param srcPos
* The start position of the source byte array.
* @param len
* The bytes length.
* @return The boolean value if successed.
* @throws MemoryNotMappedException
* If the file not mapped into memory
* @throws MemoryWriteException
* If some exception occurs when write the object.
*/
public MemoryMappedFile write(int desPos, byte[] buf, int srcPos, int len)
throws MemoryNotMappedException, MemoryWriteException {
if (buf == null)
throw new MemoryWriteException("the input data is null.");
if (mapBuf == null)
throw new MemoryNotMappedException(
"the file not mapped into memory.");
if (desPos < 0)
throw new MemoryWriteException("the memory map is underflow.");
if (desPos >= this.capacity - len)
throw new MemoryWriteException("the memory map is overflow.");
writeLock.lock();
try {
// logger.debug(Thread.currentThread().getId() + ".writing...pos:"
// + desPos + ",data:" + com.bci.imas.util.IOUtils.encodeHex(buf));
mapBuf.position(desPos);
mapBuf.put(buf, srcPos, len);
// mapBuf.force();
} finally {
writeLock.unlock();
}
return this;
}
/**
* 在内存映象的指定位置写入一个字节
*
* @param desPos
* The dest position of the memory map.
* @param b
* The byte value to be writen.
* @return The boolean value if successed.
* @throws MemoryNotMappedException
* If the file not mapped into memory
* @throws MemoryWriteException
* If some exception occurs when write the object.
*/
public MemoryMappedFile write(int desPos, byte b)
throws MemoryNotMappedException, MemoryWriteException {
if (mapBuf == null)
throw new MemoryNotMappedException(
"the file not mapped into memory.");
if (desPos < 0)
throw new MemoryWriteException("the memory map is underflow.");
if (desPos >= this.capacity)
throw new MemoryWriteException("the memory map is overflow.");
writeLock.lock();
try {
mapBuf.position(desPos);
mapBuf.put(b);
// mapBuf.force();
} finally {
writeLock.unlock();
}
return this;
}
/**
* 在内存映象的指定位置写入一个整数
*
* @param desPos
* The dest position of the memory map.
* @param i
* The integer number to be writen.
* @param len
* The integer's byte length.
* @return The boolean value if successed.
* @throws MemoryNotMappedException
* If the file not mapped into memory
* @throws MemoryWriteException
* If some exception occurs when write the object.
*/
public MemoryMappedFile write(int desPos, int i, int len)
throws MemoryNotMappedException, MemoryWriteException {
if (mapBuf == null)
throw new MemoryNotMappedException(
"the file not mapped into memory.");
if (desPos < 0)
throw new MemoryWriteException("the memory map is underflow.");
if (desPos >= this.capacity - len)
throw new MemoryWriteException("the memory map is overflow.");
writeLock.lock();
try {
mapBuf.position(desPos);
byte[] buf = new byte[len];
buf = IOUtils.intToBytes(i, len);
// logger.debug(Thread.currentThread().getId() + ".writing...pos:"
// + desPos + ",data:" + com.bci.imas.util.IOUtils.encodeHex(buf));
mapBuf.put(buf);
// mapBuf.force();
} finally {
writeLock.unlock();
}
return this;
}
/**
* 在内存映象的指定位置写入一个长整数
*
* @param desPos
* The dest position of the memory map.
* @param value
* The long number to be writen.
* @param len
* The long number's byte length.
* @return The boolean value if successed.
* @throws MemoryNotMappedException
* If the file not mapped into memory
* @throws MemoryWriteException
* If some exception occurs when write the object.
*/
public MemoryMappedFile wri
评论0