package shared; import java.io.*; import java.nio.*; import java.nio.channels.*; public class SharedMemory { private final static int DATA_UNIT = 64; private final static int HEAD_LENGTH = DATA_UNIT; private final static int TAIL_LENGTH = DATA_UNIT; private final static byte[] zero = new byte[DATA_UNIT]; private final static int FILE_BEG_TAG = 0XF1ABABF2; private final static int FILE_END_TAG = 0XF3ABABF4; private String filename; private File file; private RandomAccessFile rafile; private FileChannel channel; private MappedByteBuffer mapBuf; private int size; private int dataSize; public static class SharedMemoryException extends RuntimeException { public SharedMemoryException(Exception ex) { super(String.format("%s: %s", ex.getClass().getName(), ex.getMessage())); setStackTrace(ex.getStackTrace()); } public String toString() { return super.toString(); } } public SharedMemory(String filename, int size) { long extra = HEAD_LENGTH + TAIL_LENGTH; if (size<=extra || size%DATA_UNIT!=0) { throw new RuntimeException(String.format( "size must be multiple of %d and bigger than %d.", DATA_UNIT, extra)); } this.filename = filename; this.size = size; this.dataSize = size - HEAD_LENGTH - TAIL_LENGTH; initFile(); } private void buildMapBuffer() throws Exception { channel = rafile.getChannel(); long filesize = channel.size(); System.out.println(String.format("map size %d.", filesize)); mapBuf = channel.map(FileChannel.MapMode.READ_WRITE, 0, filesize); } private void initFile() { try { file = new File(filename); if (!file.exists()) { rafile = new RandomAccessFile(file, "rw"); int cnt = size/DATA_UNIT; while (cnt-->0) rafile.write(zero); buildMapBuffer(); mapBuf.position(0); mapBuf.putInt(FILE_BEG_TAG); mapBuf.putInt(size); mapBuf.position(HEAD_LENGTH+dataSize); mapBuf.putInt(FILE_END_TAG); mapBuf.force(); } else { rafile = new RandomAccessFile(file, "rw"); buildMapBuffer(); } } catch (Exception e) { throw new SharedMemoryException(e); } } public int getSize() { return size; } public int getStartPos() { return HEAD_LENGTH; } public int getDataSize() { return dataSize; } public FileChannel getChannel() { return channel; } public MappedByteBuffer getMapBuffer() { return mapBuf; } public FileLock lock() throws Exception { return channel.lock(); } public FileLock lock(long position, long size, boolean shared) throws Exception { return channel.lock(position, size, shared); } public FileLock tryLock() throws Exception { return channel.tryLock(); } public FileLock tryLock(long position, long size, boolean shared) throws Exception { return channel.tryLock(position, size, shared); } public static void main(String[] args) { String filename = "sharetest.txt"; int size = 1024; SharedMemory shareMemory = new SharedMemory(filename, size); System.out.println(String.format("dataSize is %d.", shareMemory.getDataSize())); } }