栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 17 实现 cls 清屏功能(与 jni 比较)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 17 实现 cls 清屏功能(与 jni 比较)

前言

以往如果需要调用C/C++代码去实现一些底层的操作,需要使用JNI(Java Native Interface)。就以cls清屏功能为例,需要自己编写相应的C/C++并生成dll文件,然后再通过JNI的方式调用dll来实现相应的功能,具体步骤可以参考这篇博客:使用JNA在Java中实现cls(命令行清屏)功能,这里展示了如何使用基于JNI的JNA框架来调用dll文件去实现cls清屏功能。而在Java 17中,我们便不再需要编写C/C++代码以及生成dll文件,而仅仅只需要写Java代码即可(目前还处于孵化器阶段),下面展示具体的使用方法。

实现

在介绍之前,先展示最终的代码:

import jdk.incubator.foreign.Clinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.ResourceScope;
import java.lang.invoke.MethodType;
import static jdk.incubator.foreign.Clinker.C_POINTER;


public class Main {

    public static void main(String[] args) throws Throwable {
        // 简单跑马灯对照效果
        var tip = "等待清屏...";
        var begin = 0;
        var end = 10;
        var interval = 1000;
        var backspaces = "b".repeat(tip.length());
        while (begin++ < end) {
            tip = tip.substring(1) + tip.charAt(0);
            System.out.print(backspaces + tip);
            Thread.sleep(interval);
            cls();
        }
        System.out.print("清屏成功");
    }

    
    private static void cls() throws Throwable {
        // 获取 system 函数
        var systemFunction = Clinker.systemLookup().lookup("system").orElseThrow();
        // 标识 system 函数的返回值及参数类型
        var systemHandle = Clinker.getInstance().downcallHandle(
                systemFunction,
                MethodType.methodType(void.class, MemoryAddress.class),
                FunctionDescriptor.ofVoid(C_POINTER)
        );
        // 获取存储在本地内存段中的 "cls" 字符串, 用于执行 system("cls") 清屏函数
        var clsStr = Clinker.toCString("cls", ResourceScope.newImplicitScope());
        // 执行 system("cls") 清屏函数
        systemHandle.invoke(clsStr.address());
    }

}

可以发现我们现在可以直接在Java中调用C/C++中的system函数并执行cls清屏命令,编写的代码也不算太多,这里结合注释也能够基本理解。

效果

下面再展示上述代码的实际效果:

配置

由于该功能仍然处于孵化器阶段,所以想要体验的话,还需要进行一些配置,下面已IDEA的配置为例进行讲解:

首先选择File -> Settings,然后找到一下配置界面:

其中Compilation options中的配置内容如下:

--add-modules jdk.incubator.foreign --add-exports java.base/jdk.internal.access=ALL-UNNAMED

然后加入如下的VM options参数:

--add-modules jdk.incubator.foreign --enable-native-access ALL-UNNAMED

完成以上配置,即可以体验cls清屏功能了,不过使用IDEA的run窗口运行会出现乱码,所以需要选择Terminal窗口,或者使用cmd命令窗口,在项目的根目录下输入以下命令即可(outproductionjni中的jni需要替换为自己的项目名):

java --add-modules jdk.incubator.foreign --enable-native-access ALL-UNNAMED -classpath outproductionjni Main
jna 方式实现

下面再简单介绍如果使用基于jni的jna实现cls的清屏功能,详细步骤可以参考使用JNA在Java中实现cls(命令行清屏)功能,这里不再展示dll文件(点击这里下载)的生成步骤:

pom的配置如下:


    8
    8
    5.10.0


    
        net.java.dev.jna
        jna
        ${jna.version}
    
    
        net.java.dev.jna
        jna-platform
        ${jna.version}
    

代码结构如下:

└─src
    └─main
        ├─java
        ├──── Cls.java
        ├──── Main.java
        │
        └─resources
            ├──── clsscreen.dll

其中clsscreen.dll即为上文提到要下载的文件。

Cls.java内容如下:

import com.sun.jna.Library;
import com.sun.jna.Native;
import java.util.Objects;


public interface Cls extends Library {

    
    String DLL_FILE_NAME = "clsscreen.dll";

    
    Cls DLL = Native.load(
        Objects.requireNonNull(Cls.class.getResource(DLL_FILE_NAME)).getPath().substring(1), Cls.class);

    
    void cls();

}

Main.java的内容如下:

import java.util.stream.Collectors;
import java.util.stream.Stream;


public class Main {

    public static void main(String[] args) throws InterruptedException {
        // 简单跑马灯对照效果
        String tip = "等待清屏...";
        int begin = 0;
        int end = 10;
        int interval = 1000;
        String backspaces = Stream.generate(() -> "b")
                .limit(tip.length())
                .collect(Collectors.joining());
        while (begin++ < end) {
            tip = tip.substring(1) + tip.charAt(0);
            System.out.print(backspaces + tip);
            Thread.sleep(interval);
            Cls.DLL.cls();
        }
        System.out.print("清屏成功");
    }

}

效果如下:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/571287.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号