关于linux:Linux下Java剪贴板的访问

37次阅读

共计 4771 个字符,预计需要花费 12 分钟才能阅读完成。

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

正文完
 0