1概述本文主要介绍如何在Linux环境下使用xsel访问系统剪贴板。2起因是在搜索引擎中直接搜索“Java访问剪贴板”,大部分都是使用AWTAPI直接访问的例子:Clipboardclipboard=Toolkit.getDefaultToolkit().getSystemClipboard();StringSelectionselection=newStringSelection("test");clipboard.setContents(selection,selection);然而,最大的问题之一是程序需要一直运行才能访问剪贴板。因此,如果没有其他处理逻辑,需要添加线程休眠代码:Clipboardclipboard=Toolkit。getDefaultToolkit().getSystemClipboard();StringSelectionselection=newStringSelection("test");clipboard.setContents(selection,selection);TimeUnit.HOURS.sleep(1);也就是说,这只是暂时复制到剪贴板,并没有永久的复制,那么在运行程序结束后,有没有其他方法可以访问剪贴板呢?3xselxsel是Linux下访问剪贴板的命令行工具。类似的还有xclip。如果没有安装,可以使用包管理器安装。写入剪贴板的命令如下:echo"testclipboard"|xsel-ib所以我想到了使用运行时:publicstaticvoidmain(String[]args)throwsException{Runtimeruntime=Runtime.getRuntime();//直接执行命令Processprocess=runtime.exec("echo\"111\"|xsel-ib");//等待执行结束process.waitFor();StringBuilder构建器=newStringBuilder();//获取输出BufferedReaderreader=newBufferedReader(newInputStreamReader(process.getInputStream()));对于(Strings;((s=reader.readLine())!=null);){builder.append(s);}System.out.println(建造者);建造者=新的StringBuilder();//获取错误输出reader=newBufferedReader(newInputStreamReader(process.getErrorStream()));对于(Strings;((s=reader.readLine())!=null);){builder.append(s);}System.out.println(建造者);//获取返回值intexitValue=process.exitValue();System.out.println("退出值是"+exitValue);如果(退出值!=0){System.out.println("错误");}process.destroy();}运行后输出如下:"111"|xsel-ib"111"|xsel-ibexitValueis0可以看到输出异常,这相当于执行了echo"\"111\"|xsel-ib",即输出的字符串都是echo4的参数上面结果的原因创建脚本文件的最大问题是Process不直接支持使用pipelineoperator,因此采用直接创建脚本运行命令的方式。步骤:创建临时脚本文件:使用Files.createFile创建权限:700权限,即拥有者的读、写、执行权限,使用Files.setPosixFilePermissions写入脚本文件:writeechostr|xsel-ib到脚本文件,使用Files.writeString执行:使用Process.exec执行脚本文件删除:使用Files.delete删除临时文件代码如下:publicstaticvoidmain(String[]args)throws异常{字符串文件名="1.sh";PathexecuteFile=Files.createFile(Path.of(fileName));Files.setPosixFilePermissions(executeFile,Set.of(PosixFilePermission.OWNER_WRITE,PosixFilePermission.OWNER_EXECUTE,PosixFilePermission.OWNER_READ));字符串剪贴板内容=“111”;Files.writeString(executeFile,"echo"+clipboardContent+"|xsel-ib");运行时runtime=Runtime.getRuntime();进程process=runtime.exec("./"+fileName);过程.waitFor();StringBuilder构建器=newStringBuilder();BufferedReaderreader=newBufferedReader(newInputStreamReader(process.getInputStream()));对于(字符串s;((s=读者。readLine())!=null);){builder.append(s);}System.out.println(建造者);建造者=新的StringBuilder();reader=newBufferedReader(newInputStreamReader(process.getErrorStream()));对于(Strings;((s=reader.readLine())!=null);){builder.append(s);}System.out.println(建造者);intexitValue=process.exitValue();System.out.println("退出值为"+exitValue);if(exitValue!=0){System.out.println("error");}Files.delete(executeFile);process.destroy();}output:exitValueis0中有两个空行,是System.out.println()的换行输出,说明Process的inputStream和errorStream都没有内容。测试结果也正常,111串可以剪掉。5从剪贴板读取从剪贴板读取原理类似,就是xsel的参数不同,这里就不展开了,放完整代码:importjava.io.BufferedReader;importjava.io.InputStreamReader;导入java.nio.file.Files;导入java.nio.file.Path;导入java.nio.file.attribute.PosixFilePermission;导入java.util.Set;公共类Main{privatestaticfinalStringFILENAME="1.sh";publicstaticvoidmain(String[]args)throwsException{writeToClipboard("111111");System.out.println(readFromClipboard());writeToClipboard("22222");System.out.println(readFromClipboard());}//写入剪贴板privatestaticvoidwriteToClipboard(Stringcontent)throwsException{PathexecuteFile=createFile("echo"+content+"|xsel-ib");执行(执行文件);}//从剪贴板读取私有静态StringreadFromClipboard()throwsException{PathexecuteFile=createFile("xsel-ob");返回执行(执行文件);}私人的estaticPathcreateFile(StringfileContent)throwsException{PathexecuteFile=Files.createFile(Path.of(FILENAME));Files.setPosixFilePermissions(executeFile,Set.of(PosixFilePermission.OWNER_WRITE,PosixFilePermission.OWNER_EXECUTE,PosixFilePermission.OWNER_READ));Files.writeString(executeFile,fileContent);返回执行文件;}privatestaticStringexec(PathexecuteFile)throwsException{Runtimeruntime=Runtime.getRuntime();进程process=runtime.exec("./"+FILENAME);过程.waitFor();StringBuilder构建器=newStringBuilder();BufferedReaderreader=newBufferedReader(newInputStreamReader(process.getInputStream()));对于(Strings;((s=reader.readLine())!=null);){builder.append(s);}字符串res="";如果(builder.length()!=0){res=builder.toString();}reader=newBufferedReader(newInputStreamReader(process.getErrorStream()));建造者=新的StringBuilder();对于(Strings;((s=reader.readLine())!=null);){builder.append(s);}if(builder.length()!=0){System.out.println(builder);}intexitValue=process.exitValue();System.out.println("退出值是"+exitValue);if(exitValue!=0){System.out.println("error");}Files.delete(executeFile);进程.destroy();返回资源;}}
