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 -ibexitValue 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;    }}