`
yuancihang
  • 浏览: 142478 次
  • 性别: Icon_minigender_1
  • 来自: 洛阳
社区版块
存档分类
最新评论

使用JNA设置系统时间

阅读更多

 最近做项目需要实现时钟同步的功能, 对于NTP协议有现成的开源库很容易实现, 但是设置系统时间JAVA本身并不支持, 看来只能访问系统库了. 把我的研究心得给大家分享.

    java是跨平台的, 所以访问系统库也要尽可能的跨平台了. 最初我希望通过调用标准C函数来实现跨平台, 实验了之后发现标准C函数只支持到秒级, 而时钟同步精度至少要到毫秒级, 很失望. 只好再找去它方法, 后来想到kernel32.dll应该是所有windows系统都有的库, 而libc.so是所有linux系统都有的库, 恩, 看来只能用这种方法来分别处理了, 也算是跨平台了.

1. 环境

     jdk1.6

     windows xp

     openSUSE11.2

2. 依赖的jar

   本程序需要依赖JNA框架.

   jna.jar

3. 接口

import java.util.Date;

public interface JNative {

    /**
     * 设置系统时间
     * @param date Date
     */
    public void setLocalTime(Date date);
   
}

 

4. windows实现



import java.util.Calendar;
import java.util.Date;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;

public class WindowsImpl implements JNative{

    public static class SYSTEMTIME extends Structure {
        public short wYear;
        public short wMonth;
        public short wDayOfWeek;
        public short wDay;
        public short wHour;
        public short wMinute;
        public short wSecond;
        public short wMilliseconds;
    }
   
    public interface Kernel32 extends Library{
       
        public boolean SetLocalTime(SYSTEMTIME st); //带时区
        public int GetCurrentProcessId();
       
    }
   
    public static Kernel32 kernel32Instance = null;
   
    public WindowsImpl(){
        kernel32Instance = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class);
    }
   
    @Override
    public void setLocalTime(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
       
        SYSTEMTIME st = new SYSTEMTIME();
        st.wYear = (short)c.get(Calendar.YEAR);
        st.wMonth = (short)(c.get(Calendar.MONTH) + 1);
        st.wDay = (short)c.get(Calendar.DAY_OF_MONTH );
        st.wDayOfWeek = (short)c.get(Calendar.DAY_OF_WEEK);
        st.wHour = (short)c.get(Calendar.HOUR_OF_DAY);
        st.wMinute = (short)c.get(Calendar.MINUTE);
        st.wSecond = (short)c.get(Calendar.SECOND);
        st.wMilliseconds = (short)c.get(Calendar.MILLISECOND);
       
        kernel32Instance.SetLocalTime(st);
    }

}

 

5. linux实现



import java.util.Date;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Structure;

public class LinuxImpl implements JNative {

    public static class tm extends Structure{
       
        public static class ByReference extends tm implements Structure.ByReference{}
        public static class ByValue extends tm implements Structure.ByValue{}
       
        public int tm_sec;//seconds 0-61
        public int tm_min;//minutes 1-59
        public int tm_hour;//hours 0-23
        public int tm_mday;//day of the month 1-31
        public int tm_mon;//months since jan 0-11
        public int tm_year;//years from 1900
        public int tm_wday;//days since Sunday, 0-6
        public int tm_yday;//days since Jan 1, 0-365
        public int tm_isdst;//Daylight Saving time indicator
    }
    public static class timeval extends Structure{
        public static class ByReference extends timeval implements Structure.ByReference{}
        public static class ByValue extends timeval implements Structure.ByValue{}
       
        public NativeLong tv_sec; /* 秒数 */
        public NativeLong tv_usec; /* 微秒数 */
    }
    public static class timezone extends Structure{
        public static class ByReference extends timezone implements Structure.ByReference{}
        public static class ByValue extends timezone implements Structure.ByValue{}
       
        public int tz_minuteswest;
        public int tz_dsttime;
    }
   
    public interface CLibrary extends Library{
       
        int gettimeofday(timeval.ByReference tv, timezone.ByReference tz);
        int settimeofday(timeval.ByReference tv, timezone.ByReference tz);
       
    }
   
    public static CLibrary cLibraryInstance = null;
   
    public LinuxImpl(){
        cLibraryInstance = (CLibrary)Native.loadLibrary("c", CLibrary.class);
    }
   
    @Override
    public void setLocalTime(Date date) {
        long ms = date.getTime();
       
        long s = ms / 1000; //秒
        long us = (ms % 1000) * 1000; //微秒
       
        timeval.ByReference tv = new timeval.ByReference();
        timezone.ByReference tz = new  timezone.ByReference();
        cLibraryInstance.gettimeofday(tv, tz);
       
        tv.tv_sec = new NativeLong(s);
        tv.tv_usec = new NativeLong(us);
        cLibraryInstance.settimeofday(tv, tz);
    }

}

 

6. 工厂类



import com.sun.jna.Platform;

public class NativeFactory {
   
    public static JNative newNative(){
        if(Platform.isWindows()){
            return new WindowsImpl();
        }
       
        return new LinuxImpl();
    }

}

 

7. 测试

public static void main(String args[]){
        System.out.println("1. " + new Date());
        JNative jNative = NativeFactory.newNative();
        jNative.setLocalTime(new Date(System.currentTimeMillis() + (10*60*1000))); //10分钟
        System.out.println("2. " + new Date());
    }

 

执行结果是系统时间增加了10分钟, 本程序在windows xp和openSUSE11.2下测试通过.

注意new Date()获取的时间为系统时间, 不是硬件时间.

  • jna.jar (921.9 KB)
  • 下载次数: 18
分享到:
评论

相关推荐

    java 使用jna开启关闭第三方应用程序.txt

    java使用jna开启关闭第三方应用程序,附简单的例子,打开一个记事本,朋友们也可以改为自己需要打开的应用程序

    使用JNA获取窗口句柄,并发送消息

    使用JNA获取窗口句柄,并发送消息 可以使用applet的方式,实现 CS架构的SSO.

    Java通过JNA调用系统API

    Java通过JNA调用系统API示例,调用 Kernel32.dll文件中的GetLocalTime(),GetSystemTime(),SetLocalTime()方法。

    JNA使用详解,包括jna.jar 和一个完整的JNA例子

    该资源中,包含jna.jar 和一个jna的函数文档。并且有一个完整的使用例子。该例子是访问本地的IC卡读卡器,其中因为原始厂商提供的本地代码函数过于发杂,为了便于JNA调用,又对本地代码...这是一个很好的JNA使用范例。

    使用JNA的jar包

    java调用C++ jna 的jar包,使用JNA去调用C++的代码,比JNI更简单,更易用

    jna-4.5.1 , jna-4.5.1-sources , jna-platform-4.5.1 jar包

    JNA提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java...

    使用JNA替代JNI调用DLL,并解决内存溢出问题

    我们上层应用平台是使用java开发的,但开放平台是使用c++开发,虽提供给我们对应的.h头文件,但在java中来解析这些数据就显然有些复杂,在实现、效率上都可能不太理想。 解决方案: 请C++同事帮忙写个dll程序,dll去...

    java 使用JNA读取ddl文件

    java 使用JNA读取ddl文件,亲测有效!

    如何使用JNA调用本地C/C++动态链接库详细示例代码

    详细演示了如何通过JNA实现以下形式的动态链接库接口: 1:基本数据类型 2:基本数据类型的指针和引用 3:结构体 4:结构体的指针和引用 5:函数指针和回调函数 6:字符串指针 7:输入一个数组 8:输出一个数组并...

    使用JNA 调用WINDOWS API

    一直以为调用本地链接库函数的时候一定要借助JNI或者SWT来实现,一日中无意看到JNA,发现它也可以实现这类调用

    JNA 使用方法

    JNA可以让你像调用一般java方法一样直接调用本地方法。就和直接执行本地方法差不多,而且调用本地方法还不用额外的其他处理或者配置什么的,也不需要多余的引用或者编码,使用很方便。 文档写的很全。

    JNA实例 JNA实例 JNA实例

    JNA实例=======================================================JNA实例

    jna-5.5.0.jar中文文档.zip

    jna-***.jar中文文档.zip,java,jna-***.jar,net.java.dev.jna,jna,***,com.sun.jna,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 ...

    jna-4.1.0-API文档-中文版.zip

    赠送jar包:jna-4.1.0.jar; 赠送原API文档:jna-4.1.0-javadoc.jar; 赠送源代码:jna-4.1.0-sources.jar; 赠送Maven依赖信息文件:jna-4.1.0.pom; 包含翻译后的API文档:jna-4.1.0-javadoc-API文档-中文(简体)版...

    jna-4.3.0-API文档-中文版.zip

    赠送jar包:jna-4.3.0.jar; 赠送原API文档:jna-4.3.0-javadoc.jar; 赠送源代码:jna-4.3.0-sources.jar; 赠送Maven依赖信息文件:jna-4.3.0.pom; 包含翻译后的API文档:jna-4.3.0-javadoc-API文档-中文(简体)版...

    java使用jna接入C++的DLL

    java接入C++的DLL(奇迹云答题器答题) 示例代码 使用jna接入 该DLL为32位DLL 开发环境必须与jdk-1.7-32位的包括tomcat的jdk支持库 必须为jdk1.7-32位 否则会报错

    jna5.5.0--5.3.0.rar

    SetLocalTime():设置本地时间。注:此方法需要系统管理员权限。 通过查询知道这些方法都封装在kernel32.dll文件中,下面进行调用。 最后说一下,实在看不贯某些同学,公共的开源资源,赚取大量积分的行为。

    jna-5.4.0.jar中文文档.zip

    jna-***.jar中文文档.zip,java,jna-***.jar,net.java.dev.jna,jna,***,com.sun.jna,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 ...

    fuse-jna, 没有废话,实际上使用Java绑定来使用JNA进行.zip

    fuse-jna, 没有废话,实际上使用Java绑定来使用JNA进行 dope拿着它git clone git://github.com/EtiennePerot/fuse-jna.git运行它fuse-jna/examples/hellofs.sh ~/hellof

    jna-5.0.0.jar中文文档.zip

    jna-***.jar中文文档.zip,java,jna-***.jar,net.java.dev.jna,jna,***,com.sun.jna,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 ...

Global site tag (gtag.js) - Google Analytics