java实现内存共享的意义链接:https://www.cnblogs.com/swbzmx/p/5992247.html
代码原地址:https://www.iteye.com/blog/huxu1986-163-com-2163251
自己总结的内容(可以执行)
package com.hx.sharemem;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Properties;
import com.hx.util.FileUtil;
/**
* 共享内存操作类
* @author hx
*
*/
public class ShareMemory {
int flen = 41779264; //开辟共享内存大小
int fsize = 0; //文件的实际大小
String shareFileName; //共享内存文件名
String sharePath; //共享内存路径
MappedByteBuffer mapBuf = null; //定义共享内存缓冲区
FileChannel fc = null; //定义相应的文件通道
FileLock fl = null; //定义文件区域锁定的标记。
Properties p = null;
RandomAccessFile RAFile = null; //定义一个随机存取文件对象
/**
*
* @param sp 共享内存文件路径
* @param sf 共享内存文件名
*/
public ShareMemory(String sp, String sf) {
//如果没有文件
if (sp.length() != 0) {
//调用 FileUtil中的CreateDir(sp)方法创建文件夹
FileUtil.CreateDir(sp);
//路径为创建好的文件夹加上,File.separator与系统有关的默认名称分隔符
this.sharePath = sp + File.separator;
} else {
this.sharePath = sp;
}
this.shareFileName = sf;
try {
// 获得一个只读的随机存取文件对象 "rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
RAFile = new RandomAccessFile(this.sharePath + this.shareFileName + ".sm", "rw");
//获取相应的文件通道
fc = RAFile.getChannel();
//获取实际文件的大小
fsize = (int) fc.size();
//比较实际文件的大小和开辟共享内存大小
if (fsize < flen) {
//计算剩余的内存大小
byte bb[] = new byte[flen - fsize];
//创建字节缓冲区
ByteBuffer bf = ByteBuffer.wrap(bb);
//清除bf中的数据
bf.clear();
//设置此通道的文件位置。
fc.position(fsize);
//将字节序列从给定的缓冲区写入此通道。
fc.write(bf);
fc.force(false);
fsize = flen;
}
//将此通道的文件区域直接映射到内存中。
mapBuf = fc.map(FileChannel.MapMode.READ_WRITE, 0, fsize);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* @param ps 锁定区域开始的位置;必须为非负数
* @param len 锁定区域的大小;必须为非负数
* @param buff 写入的数据
* @return
*/
public synchronized int write(int ps, int len, byte[] buff) {
//fsize为文件的实际大小,在这里为0
if (ps >= fsize || ps + len >= fsize) {
return 0;
}
//定义文件区域锁定的标记。
FileLock fl = null;
try {
//获取此通道的文件给定区域上的锁定。
//position:锁定文件中的开始位置
//size: 锁定文件中的内容长度
//shared: 是否使用共享锁。true为共享锁定;false为独占锁定
fl = fc.lock(ps, len, false);
if (fl != null) {
//mapBuf定义共享内存缓冲区,.position(ps)设置当前操作位置
mapBuf.position(ps);
//创建字节缓冲区
ByteBuffer bf1 = ByteBuffer.wrap(buff);
//此方法将给定源缓冲区中的剩余字节传输到此缓冲区中。如果源缓冲区中的剩余字节多于此缓冲区中的剩余字节
mapBuf.put(bf1);
//释放此锁定。
fl.release();
return len;
}
} catch (Exception e) {
if (fl != null) {
try {
fl.release();
} catch (IOException e1) {
System.out.println(e1.toString());
}
}
return 0;
}
return 0;
}
/**
*
* @param ps 锁定区域开始的位置;必须为非负数
* @param len 锁定区域的大小;必须为非负数
* @param buff 要取的数据
* @return
*/
public synchronized int read(int ps, int len, byte[] buff) {
if (ps >= fsize) {
return 0;
}
//定义文件区域锁定的标记。
FileLock fl = null;
try {
fl = fc.lock(ps, len, false);
if (fl != null) {
//System.out.println( "ps="+ps );
mapBuf.position(ps);
if (mapBuf.remaining() < len) {
len = mapBuf.remaining();
}
if (len > 0) {
mapBuf.get(buff, 0, len);
}
fl.release();
return len;
}
} catch (Exception e) {
if (fl != null) {
try {
fl.release();
} catch (IOException e1) {
System.out.println(e1.toString());
}
}
return 0;
}
return 0;
}
/**
* 完成,关闭相关操作
*/
protected void finalize() throws Throwable {
if (fc != null) {
try {
fc.close();
} catch (IOException e) {
System.out.println(e.toString());
}
fc = null;
}
if (RAFile != null) {
try {
RAFile.close();
} catch (IOException e) {
System.out.println(e.toString());
}
RAFile = null;
}
mapBuf = null;
}
/**
* 关闭共享内存操作
*/
public synchronized void closeSMFile() {
if (fc != null) {
try {
fc.close();
} catch (IOException e) {
System.out.println(e.toString());
}
fc = null;
}
if (RAFile != null) {
try {
RAFile.close();
} catch (IOException e) {
System.out.println(e.toString());
}
RAFile = null;
}
mapBuf = null;
}
/**
* 检查退出
* @return true-成功,false-失败
*/
public synchronized boolean checkToExit() {
byte bb[] = new byte[1];
if (read(1, 1, bb) > 0) {
if (bb[0] == 1) {
return true;
}
}
return false;
}
/**
* 复位退出
*/
public synchronized void resetExit() {
byte bb[] = new byte[1];
bb[0] = 0;
write(1, 1, bb);
}
/**
* 退出
*/
public synchronized void toExit() {
byte bb[] = new byte[1];
bb[0] = 1;
write(1, 1, bb);
}
public static void main(String arsg[]) throws Exception{
ShareMemory sm = new ShareMemory("D://demo","test");
String str = "中文测试工控综合系统";
sm.write(40, 20, str.getBytes("UTF-8"));
byte[] b = new byte[20];
sm.read(40, 20, b);
System.out.println(new String(b,"UTF-8"));
}
}
package com.hx.util;
import java.io.File;
public class FileUtil {
public static void CreateDir(String sp) {
try {
File f = new File(sp);
if(!f.exists()){
f.mkdirs();//创建目录
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}