java实现共享内存

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();
        }


    }

    }



  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值