⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memorymappedfile.java

📁 java的共享内存管理.基于MMF设计。封装了java.nio.MappedByteBuffer.在大流量实时业务系统时
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * @(#)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 write(int desPos, long value, 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.longToBytes(value, 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 s
	 *            The string 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 writting the data
	 */
	public MemoryMappedFile write(int desPos, String s)
			throws MemoryWriteException, MemoryNotMappedException {
		if (s == 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 - s.length())
			throw new MemoryWriteException("the memory map is overflow.");
		writeLock.lock();
		try {
			mapBuf.position(desPos);
			byte[] buf = s.getBytes();
			// 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.
	 * @return The StoredMessage object.
	 * @see com.bci.commons.mmf.cell.AbstractCell
	 * @throws MemoryNotMappedException
	 *             If the file not mapped into memory
	 * @throws MemoryReadException
	 *             If some exception occurs when reading the memory.
	 */
	public abstract AbstractCell read(int desPos) throws MemoryMapException,
			MemoryReadException;

	/**
	 * 在内存映象的指定位置读取一个字节数据
	 * 
	 * @param pos
	 *            The dest position of the memory map.
	 * @return The byte value if successed.
	 * @throws MemoryNotMappedException
	 *             If the file not mapped into memory
	 * @throws MemoryReadException
	 *             If some exception occurs when reading the memory.
	 */
	public byte readByte(int pos) throws MemoryNotMappedException,
			MemoryReadException {
		if (mapBuf == null)
			throw new MemoryNotMappedException(
					"the file not mapped into memory.");
		if (pos < 0)
			throw new MemoryReadException("the memory map is underflow.");
		if (pos > this.capacity - 1)
			throw new MemoryReadException("the memory map is overflow.");
		readLock.lock();
		try {
			mapBuf.position(pos);
			return mapBuf.get();
		} finally {
			readLock.unlock();
		}
	}

	/**
	 * 在内存映象的指定位置读取一个短整数
	 * 
	 * @param pos
	 *            The dest position of the memory map.
	 * @return The short nubmer if successed.
	 * @throws MemoryNotMappedException
	 *             If the file not mapped into memory
	 * @throws MemoryReadException
	 *             If some exception occurs when reading the memory.
	 */
	public short readShort(int pos) throws MemoryNotMappedException,
			MemoryReadException {
		if (mapBuf == null)
			throw new MemoryNotMappedException(
					"the file not mapped into memory.");
		if (pos < 0)
			throw new MemoryReadException("the memory map is underflow.");
		if (pos > this.capacity - 2)
			throw new MemoryReadException("the memory map is overflow.");
		readLock.lock();
		try {
			mapBuf.position(pos);
			return mapBuf.getShort();
		} finally {
			readLock.unlock();
		}
	}

	/**
	 * 在内存映象的指定位置读取一个整数
	 * 
	 * @param pos
	 *            The dest position of the memory map.
	 * @return The integer nubmer if successed.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -