最近做项目需要实现时钟同步的功能, 对于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()获取的时间为系统时间, 不是硬件时间.
分享到:
相关推荐
java使用jna开启关闭第三方应用程序,附简单的例子,打开一个记事本,朋友们也可以改为自己需要打开的应用程序
使用JNA获取窗口句柄,并发送消息 可以使用applet的方式,实现 CS架构的SSO.
Java通过JNA调用系统API示例,调用 Kernel32.dll文件中的GetLocalTime(),GetSystemTime(),SetLocalTime()方法。
该资源中,包含jna.jar 和一个jna的函数文档。并且有一个完整的使用例子。该例子是访问本地的IC卡读卡器,其中因为原始厂商提供的本地代码函数过于发杂,为了便于JNA调用,又对本地代码...这是一个很好的JNA使用范例。
java调用C++ jna 的jar包,使用JNA去调用C++的代码,比JNI更简单,更易用
JNA提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java...
我们上层应用平台是使用java开发的,但开放平台是使用c++开发,虽提供给我们对应的.h头文件,但在java中来解析这些数据就显然有些复杂,在实现、效率上都可能不太理想。 解决方案: 请C++同事帮忙写个dll程序,dll去...
java 使用JNA读取ddl文件,亲测有效!
详细演示了如何通过JNA实现以下形式的动态链接库接口: 1:基本数据类型 2:基本数据类型的指针和引用 3:结构体 4:结构体的指针和引用 5:函数指针和回调函数 6:字符串指针 7:输入一个数组 8:输出一个数组并...
一直以为调用本地链接库函数的时候一定要借助JNI或者SWT来实现,一日中无意看到JNA,发现它也可以实现这类调用
JNA可以让你像调用一般java方法一样直接调用本地方法。就和直接执行本地方法差不多,而且调用本地方法还不用额外的其他处理或者配置什么的,也不需要多余的引用或者编码,使用很方便。 文档写的很全。
JNA实例=======================================================JNA实例
jna-***.jar中文文档.zip,java,jna-***.jar,net.java.dev.jna,jna,***,com.sun.jna,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 ...
赠送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文档-中文(简体)版...
赠送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接入C++的DLL(奇迹云答题器答题) 示例代码 使用jna接入 该DLL为32位DLL 开发环境必须与jdk-1.7-32位的包括tomcat的jdk支持库 必须为jdk1.7-32位 否则会报错
SetLocalTime():设置本地时间。注:此方法需要系统管理员权限。 通过查询知道这些方法都封装在kernel32.dll文件中,下面进行调用。 最后说一下,实在看不贯某些同学,公共的开源资源,赚取大量积分的行为。
jna-***.jar中文文档.zip,java,jna-***.jar,net.java.dev.jna,jna,***,com.sun.jna,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 ...
fuse-jna, 没有废话,实际上使用Java绑定来使用JNA进行 dope拿着它git clone git://github.com/EtiennePerot/fuse-jna.git运行它fuse-jna/examples/hellofs.sh ~/hellof
jna-***.jar中文文档.zip,java,jna-***.jar,net.java.dev.jna,jna,***,com.sun.jna,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 ...