IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux下Java剪贴板的访问 -> 正文阅读

[系统运维]Linux下Java剪贴板的访问

1 概述

本文主要讲述了如何利用xselLinux环境下对系统剪贴板的访问。

2 起因

在搜索引擎直接搜索“Java访问剪贴板”,大部分都是直接使用AWT API进行访问的例子:

Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection selection = new StringSelection("test");
clipboard.setContents(selection, selection);

但是,一个最大的问题是,需要该程序一直运行,才能访问到剪贴板,因此,如果没有其他处理逻辑,需要加上线程休眠代码:

Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection selection = new StringSelection("test");
clipboard.setContents(selection, selection);
TimeUnit.HOURS.sleep(1);

换句话说,这样只是临时复制到剪贴板,并没有永久复制,那么,有没有其他办法可以在运行程序结束之后也能访问到剪贴板呢?

3 xsel

xselLinux下访问剪贴板的命令行工具,类似的还有xclip,没有安装的可以使用包管理器安装。其中写入到剪贴板命令如下:

echo "test clipboard" | xsel -ib

由此想到了可以尝试使用Runtime

public static void main(String[] args) throws Exception {
    Runtime runtime = Runtime.getRuntime();
    // 直接执行命令
    Process process = runtime.exec("echo \"111\" | xsel -ib");
    // 等待执行结束
    process.waitFor();
    StringBuilder builder = new StringBuilder();
    // 获取输出
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    for (String s; ((s = reader.readLine()) != null); ) {
        builder.append(s);
    }
    System.out.println(builder);
    builder = new StringBuilder();
    // 获取错误输出
    reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
    for (String s; ((s = reader.readLine()) != null); ) {
        builder.append(s);
    }
    System.out.println(builder);
    // 获取返回值
    int exitValue = process.exitValue();
    System.out.println("exitValue is " + exitValue);
    if (exitValue != 0) {
        System.out.println("error");
    }
    process.destroy();
}

运行之后输出如下:

"111" | xsel -ib
"111" | xsel -ib
exitValue is 0

可以看到输出结果是不正常的,这样就相当于变成了执行

echo "\"111\" | xsel -ib"

也就是输出的字符串都是echo的参数。

4 创建脚本文件

出现上面结果的原因是Process并不能直接支持使用管道运算符,因此,采用直接创建脚本运行命令的方法。

步骤:

  • 创建临时脚本文件:使用Files.createFile创建
  • 授权:700权限,也就是所有者读、写、执行权限,使用Files.setPosixFilePermissions
  • 写入脚本文件:向脚本文件写入echo str | xsel -ib,使用Files.writeString
  • 执行:利用Process.exec执行脚本文件
  • 删除:利用Files.delete删除临时文件

代码如下:

public static void main(String[] args) throws Exception {
    String fileName = "1.sh";
    Path executeFile = Files.createFile(Path.of(fileName));
    Files.setPosixFilePermissions(executeFile, Set.of(PosixFilePermission.OWNER_WRITE,
            PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.OWNER_READ));
    String clipboardContent = "111";
    Files.writeString(executeFile, "echo " + clipboardContent + " | xsel -ib");
    Runtime runtime = Runtime.getRuntime();
    Process process = runtime.exec("./" + fileName);
    process.waitFor();
    StringBuilder builder = new StringBuilder();
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    for (String s; ((s = reader.readLine()) != null); ) {
        builder.append(s);
    }
    System.out.println(builder);
    builder = new StringBuilder();
    reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
    for (String s; ((s = reader.readLine()) != null); ) {
        builder.append(s);
    }
    System.out.println(builder);
    int exitValue = process.exitValue();
    System.out.println("exitValue is " + exitValue);
    if (exitValue != 0) {
        System.out.println("error");
    }
    Files.delete(executeFile);
    process.destroy();
}

输出:



exitValue is 0

有两行空行是System.out.println()的换行输出,说明ProcessinputStream以及errorStream都没有内容。

测试结果也是正常,能够剪贴出111字符串。

5 从剪贴板读取

从剪贴板读取的原理类似,就是xsel的参数不一样,这里不展开了,放上完整代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Set;

public class Main {
    private static final String FILENAME = "1.sh";

    public static void main(String[] args) throws Exception {
        writeToClipboard("111111");
        System.out.println(readFromClipboard());
        writeToClipboard("22222");
        System.out.println(readFromClipboard());
    }

	//写入到剪贴板
    private static void writeToClipboard(String content) throws Exception {
        Path executeFile = createFile("echo " + content + " | xsel -ib");
        exec(executeFile);
    }

	//从剪贴板读取
    private static String readFromClipboard() throws Exception {
        Path executeFile = createFile("xsel -ob");
        return exec(executeFile);
    }

    private static Path createFile(String fileContent) throws Exception {
        Path executeFile = Files.createFile(Path.of(FILENAME));
        Files.setPosixFilePermissions(executeFile, Set.of(PosixFilePermission.OWNER_WRITE,
                PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.OWNER_READ));
        Files.writeString(executeFile, fileContent);
        return executeFile;
    }

    private static String exec(Path executeFile) throws Exception {
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec("./" + FILENAME);
        process.waitFor();
        StringBuilder builder = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        for (String s; ((s = reader.readLine()) != null); ) {
            builder.append(s);
        }
        String res = "";
        if (builder.length() != 0) {
            res = builder.toString();
        }
        reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        builder = new StringBuilder();
        for (String s; ((s = reader.readLine()) != null); ) {
            builder.append(s);
        }
        if (builder.length() != 0) {
            System.out.println(builder);
        }
        int exitValue = process.exitValue();
        System.out.println("exitValue is " + exitValue);
        if (exitValue != 0) {
            System.out.println("error");
        }
        Files.delete(executeFile);
        process.destroy();
        return res;
    }
}
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-13 12:00:08  更:2022-05-13 12:00:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年6日历 -2024/6/29 18:46:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码