有一些奇怪的问题,但是我遇到了在Windows 7上使用mklink
创建符号链接的问题。由于使用{{1}时存在260个字符限制,我正在做一些有点奇怪的事情通过使用cmd.exe
在我的Java源代码中创建符号链接。由于我无法解释它,这里是代码:
Process
我得到的错误:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
public class WindowsSymlinkUtility {
private List<String> command, currentSymlinks;
public WindowsSymlinkUtility() {
this.command = this.currentSymlinks = new ArrayList<String>();
this.command.add("cmd.exe");
this.command.add("/C");
}
/**
* Automatically creates a directory junction
* @param String link - the path and name of the symlink
* @param String target - the directory to point the symlink to
* @return boolean
* @see http://ss64.com/nt/mklink.html
*/
public boolean createSymlink(String link, String target) {
return createSymlink("\\J", link, target);
}
/**
*
* @param String flag - the flag for mklink
* @param String link - the path and name of the symlink
* @param String target - the directory to point the symlink to
* @return boolean
* @see http://ss64.com/nt/mklink.html
*/
public boolean createSymlink(String flag, String link, String target) {
this.command.clear();
this.command.add("mklink");
this.command.add(flag);
this.command.add(link);
this.command.add(target);
this.currentSymlinks.add(link);
return this.runner() == 0;
}
public boolean removeSymlink(String link) {
this.command.clear();
this.command.add("RD");
this.command.add(link);
if(this.runner() != 0) {
this.command.clear();
this.command.add("DEL");
this.command.add(link);
} else {
return true;
}
return this.runner() == 0;
}
public boolean removeAllSymlinks() {
for(String link : this.currentSymlinks) {
if(!this.removeSymlink(link)) {
return false;
}
}
return true;
}
/**
* Leave for debugging purposes
* @return String
*/
public String getCurrentCommand() {
String cmd = "";
for(String part : this.command) {
cmd += part + " ";
}
return cmd;
}
private int runner() {
Process process = null;
String message = null;
BufferedInputStream bis = null;
int exitVal = -1;
StringBuilder strBuff = new StringBuilder();
try {
if(this.command.size() < 1) throw new Exception("Length of Windows command cannot be zero");
ProcessBuilder pb = new ProcessBuilder(this.command);
Map<String, String> envVars = pb.environment();
pb.directory();
pb.redirectErrorStream(true);
process = pb.start();
bis = new BufferedInputStream(process.getInputStream());
byte[] bArr = new byte[2048];
while (bis.read(bArr) != -1) {
strBuff.append(new String(bArr).trim());
bArr = new byte[2048];
}
exitVal = process.waitFor();
message = strBuff.toString();
} catch(Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
System.err.println(message);
}
return exitVal;
}
public static void main(String[] args) {
WindowsSymlinkUtility foo = new WindowsSymlinkUtility();
foo.createSymlink("%TEMP%\\foo", "C:\\Users\\djthomps\\Downloads");
}
}
您可能会遇到一些问题:
以下是我的问题:
java.io.IOException: Cannot run program "mklink": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
at WindowsSymlinkUtility.runner(WindowsSymlinkUtility.java:113)
at WindowsSymlinkUtility.createSymlink(WindowsSymlinkUtility.java:56)
at WindowsSymlinkUtility.createSymlink(WindowsSymlinkUtility.java:37)
at WindowsSymlinkUtility.main(WindowsSymlinkUtility.java:134)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(Unknown Source)
at java.lang.ProcessImpl.start(Unknown Source)
... 5 more
Cannot run program "mklink": CreateProcess error=2, The system cannot find the file specified
null
代替SET
吗?mklink
?同样,我明白这是一个奇怪的问题。如果有什么不妥,请要求澄清。
答案 0 :(得分:2)
我已经修改了你的程序只是为了提供一个工作样本...本质上问题是你没有连接变量并将它们作为一个参数传递给cmd
。
一个实现说明:: 不使用del
删除符号链接,否则目标目录中的所有文件都将被删除。使用我为后人添加的rmdir
。
/**
* @author Edward Beckett :: <Edward@EdwardBeckett.com>
* @since :: 7/21/2015
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class WindowsSymlinkUtility {
public static final String D_LINK = "/D";
public static final String H_LINK = "/H";
public static final String J_LINK = "/J";
public static final String REM_LINK = "rmdir";
private String command = "";
private String link = "";
private String target = "";
private List<String> commands = Arrays.asList( D_LINK, H_LINK, J_LINK, REM_LINK );
public void createSymlink( String command, String link, String target ) {
this.command = command;
this.link = link;
this.target = target;
if( !commands.contains( command ) ) {
System.out.println( command + " Is not a valid command \n " );
return;
}
runner();
}
private void runner() {
try {
String[] values = { "CMD", "/C", "mklink", this.command, this.link, this.target };
ProcessBuilder builder = new ProcessBuilder( values );
builder.directory( new File( this.link ) );
Process process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader( is );
BufferedReader br = new BufferedReader( isr );
String line;
System.out.printf( "Output of running %s is:\n",
Arrays.toString( values ) );
while( ( line = br.readLine() ) != null ) {
System.out.println( line );
int exitValue = process.waitFor();
System.out.println( "\n\nExit Value is " + exitValue );
}
} catch( InterruptedException | IOException e ) {
e.printStackTrace();
}
}
public static void main( String[] args ) {
( new WindowsSymlinkUtility() ).createSymlink( J_LINK, "C:\\Foo", "C:\\Temp" );
}
}
输出
Output of running [CMD, /C, mklink, /J, C:\Foo, C:\Temp] is:
Junction created for C:\Foo <<===>> C:\Temp
Exit Value is 0
答案 1 :(得分:0)
Eddie B的解决方案在正确的轨道上但是当Java试图运行命令时我一直遇到错误。这是我的演绎有效:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
public class WindowsSymlinkUtility {
public static final String D_LINK = "/D";
public static final String H_LINK = "/H";
public static final String J_LINK = "/J";
public static final String REM_LINK = "rmdir";
private String command, flag, link, target;
private List<String> commands = Arrays.asList(D_LINK, H_LINK, J_LINK, REM_LINK), symlinks;
public WindowsSymlinkUtility() {
this.command = this.flag = this.link = this.target = "";
this.symlinks = new ArrayList<>();
}
/**
* Automatically creates a directory junction
* @param String link - the path and name of the symlink
* @param String target - the directory to point the symlink to
* @return boolean
* @see http://ss64.com/nt/mklink.html
*/
public boolean createSymlink(String link, String target) {
return createSymlink(J_LINK, link, target);
}
/**
*
* @param String flag - the flag for mklink
* @param String link - the path and name of the symlink
* @param String target - the directory to point the symlink to
* @return boolean
* @see http://ss64.com/nt/mklink.html
*/
public boolean createSymlink(String flag, String link, String target) {
if(!this.commands.contains(flag)) {
System.err.printf("%s is not a valid command\n", flag);
return false;
}
this.command = "mklink";
this.flag = flag;
this.link = link;
this.target = target;
if(this.runner() == 0) {
this.symlinks.add(this.link);
return true;
}
return false;
}
private int runner() {
Process process = null;
String message = null;
BufferedInputStream bis = null;
StringBuilder strBuff = new StringBuilder();
int exitVal = -1;
try {
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", this.command, this.flag, this.link, this.target);
Map<String, String> envVars = pb.environment();
pb.directory();
pb.redirectErrorStream(true);
process = pb.start();
bis = new BufferedInputStream(process.getInputStream());
byte[] bArr = new byte[2048];
while (bis.read(bArr) != -1) {
strBuff.append(new String(bArr).trim());
bArr = new byte[2048];
}
exitVal = process.waitFor();
message = strBuff.toString();
System.out.println(message);
} catch(Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
System.err.println(message);
}
return exitVal;
}
public static void main(String[] args) {
(new WindowsSymlinkUtility()).createSymlink(J_LINK, "%TEMP%\\node", "C:\\users\\djthomps\\Downloads");
}
}