`
yuancihang
  • 浏览: 145169 次
  • 性别: 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调用系统API

    // 获取系统时间并设置本地时间的代码... } } ``` 这里,我们创建了`Kernel32`接口的实例,并使用`GetLocalTime()`获取了本地时间。然后,可以遍历`SYSTEMTIME`结构体的字段,将时间信息格式化后输出。 5. **...

    JNA相关包 jna.jar

    例如,如果你想要在Java中获取系统时间,可以使用`com.sun.jna.platform.win32Kernel32`类中的`GetSystemTimeAsFileTime()`方法,而在Unix系统中,可以使用`com.sun.jna.platform.unixLibc`类的`time()`方法。这些类...

    JNA框架帮助文档

    它支持Windows、Unix、Linux以及Mac OS X等操作系统,并且可以轻松地跨平台使用。 **2. JNA的优势** - **无需C代码**: 使用JNA,开发者无需编写C代码即可调用本地库。 - **简化开发**: JNA提供了一种更加简单和...

    jna技术手册和教程

    例如,通过JNA,你可以轻松地调用Windows API来获取系统时间,或者在Linux上使用POSIX函数进行进程管理。在提供的"娣卞叆娴呭嚭JNA鈥斿揩閫熻皟鐢ㄥ師鐢熷嚱鏁_.0.pdf"教程中,可能会包含具体的示例代码,演示如何...

    jna和examples的jar包

    对于 JFrame 的透明度,JNA 可能被用来调用操作系统级别的 API 来设置窗口属性,比如 Windows 上的 `SetLayeredWindowAttributes` 函数或 X11 系统的 `XSetWindowAttributes` 函数。不规则形状的 JFrame 则可能涉及...

    jna相关jar包

    1. **无需JNI**:使用JNA,开发者可以避免编写JNI代码,减少错误和调试时间。 2. **自动类型映射**:JNA可以自动将Java类型映射为本地类型,如int、double、字符串等。 3. **数组和结构体支持**:JNA能够处理数组和...

    Java设置window系统时间,精确到毫秒

    目前Java没有直接设置系统时间精确到毫秒的方法,这里结合C可以时间。使用Java代码调用C库。

    jna5.5.0--5.3.0.rar

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

    JNA_API.zip_JNA API_jna_jna api_jna 帮助文档_speciesmux

    下面的例子展示了如何使用JNA获取当前系统时间: ```java import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinBase; ...

    开源项目JNA-中文翻译版

    - **平台兼容性**:JNA支持多种操作系统,包括Unix、Linux、Windows和Mac OS X。 #### 三、JNA的使用示例 ##### 1. JNA入门 - **准备工作**:首先,需要下载并配置`jna.jar` 和 `example.jar` 文件。 - **环境...

    java jna platform

    这个库让开发者能够更容易地访问特定于操作系统的功能,例如文件系统、用户管理、网络设置等。在`platform.jar`中,已经封装了大量的常见操作系统函数,减少了开发者自行查找和映射原生API的繁琐工作。 使用Java ...

    Java设置linux系统时间

    利用Java代码设置Linux系统时间。设置时间精确到毫秒级别。

    JNA库文件和文档

    Java Native Access(JNA)是Java平台上的一个开源库,它提供了一种简单的方法来调用平台本机库,无需编写JNI(Java ...通过深入理解和熟练使用JNA,Java开发者可以充分利用本地系统的功能,提高应用程序的性能和功能。

    Highcharts动态曲线图(使用jna监视cpu使用率)

    5. 实时更新图表数据,可以设置定时器每隔一定时间调用JNA获取新的CPU使用率,并添加到图表中。 这样,你就可以得到一个实时显示CPU使用率的动态曲线图,这对于监控系统性能或分析数据趋势非常有用。注意,确保你的...

    jna和JNative

    JNI适合对性能有严格要求且愿意投入更多时间在本地代码上的项目,而JNA则为开发者提供了便利,牺牲了一定的性能以换取开发效率。在实际应用中,应根据项目需求和团队能力选择合适的方法。无论是JNI还是JNA,它们都极...

    JNI与JNA性能的比较.docx

    2. **调用机制**:JNI使用系统调用直接调用本地函数,而JNA通过Java的反射机制进行调用,反射通常比直接调用慢。 3. **内存管理**:JNI允许直接操作内存,而JNA由Java自动管理内存,这可能导致额外的内存复制和垃圾...

    开源项目JNA-中文翻译版.pdf

    - **避免使用C语言**:JNA最大的优势之一就是它允许开发者直接使用Java代码调用本地系统API,无需编写任何C代码。这极大地简化了开发流程,减少了潜在的错误和问题。 - **减少错误和维护成本**:使用JNI时常见的...

    Java_并发核心编程-中文翻译_英文原版开源项目JNA-中文翻译版

    Java并发核心编程是Java开发中的重要领域,它涉及到如何在多线程环境下高效地执行代码...而JNA的使用则为Java与本地系统的交互提供了便利,但也带来了额外的并发挑战,需要开发者具备扎实的并发基础知识才能有效应对。

    jna-wrapper:JNA 包装器(Java 本机访问 - https

    **Java Native Access (JNA)** 是一个 ...如果你需要与操作系统底层进行交互,或者使用特定的本机库,JNA 可能是一个值得考虑的选择。通过深入学习和实践,你可以掌握 JNA 的使用,提升 Java 应用程序的功能和性能。

    java读取注册表信息

    注册表是Windows操作系统中的一个重要数据库,存储了系统的配置信息,如软件设置、硬件设备信息等。Java本身并不直接支持读取注册表,但我们可以借助第三方库,比如JNA(Java Native Access)或者Jacob(Java ...

Global site tag (gtag.js) - Google Analytics