Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在JVM运行时在Windows上创建符号链接_Java_Windows_Windows 7_Cmd - Fatal编程技术网

Java 在JVM运行时在Windows上创建符号链接

Java 在JVM运行时在Windows上创建符号链接,java,windows,windows-7,cmd,Java,Windows,Windows 7,Cmd,有些奇怪的问题,但我在Windows7上使用mklink创建符号链接时遇到了一些问题。由于使用cmd.exe时存在260个字符的限制,我正在做一些奇怪的事情,使用Process在我的Java源代码中创建符号链接。因为我不能很好地解释它,下面是代码: import java.io.BufferedInputStream; import java.io.BufferedReader; import java.util.ArrayList; import java.util.List; import

有些奇怪的问题,但我在Windows7上使用
mklink
创建符号链接时遇到了一些问题。由于使用
cmd.exe
时存在260个字符的限制,我正在做一些奇怪的事情,使用
Process
在我的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 {

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

}
import java.io.BufferedInputStream;
导入java.io.BufferedReader;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Map;
导入java.util.array;
公共类WindowsSymlinkUtility{
私有列表命令,currentSymlinks;
公共WindowsSymlinkUtility(){
this.command=this.currentSymlinks=new ArrayList();
add(“cmd.exe”);
此.command.add(“/C”);
}
/**
*自动创建目录连接
*@param String link-符号链接的路径和名称
*@param String target-指向符号链接的目录
*@返回布尔值
*@见http://ss64.com/nt/mklink.html
*/
公共布尔createSymlink(字符串链接,字符串目标){
返回createSymlink(“\\J”,链接,目标);
}
/**
*
*@param字符串标志-mklink的标志
*@param String link-符号链接的路径和名称
*@param String target-指向符号链接的目录
*@返回布尔值
*@见http://ss64.com/nt/mklink.html
*/
公共布尔createSymlink(字符串标志、字符串链接、字符串目标){
this.command.clear();
此.command.add(“mklink”);
this.command.add(标志);
this.command.add(link);
this.command.add(目标);
此.currentSymlinks.add(链接);
返回此。runner()==0;
}
公共布尔removeSymlink(字符串链接){
this.command.clear();
此.command.add(“RD”);
this.command.add(link);
if(this.runner()!=0){
this.command.clear();
此.command.add(“DEL”);
this.command.add(link);
}否则{
返回true;
}
返回此。runner()==0;
}
公共布尔removeAllSymlinks(){
for(字符串链接:this.currentSymlinks){
如果(!this.removeSymlink(link)){
返回false;
}
}
返回true;
}
/**
*留作调试之用
*@返回字符串
*/
公共字符串getCurrentCommand(){
字符串cmd=“”;
for(字符串部分:this.command){
cmd+=零件+“”;
}
返回cmd;
}
私有int runner(){
Process=null;
字符串消息=null;
BufferedInputStream bis=null;
int exitVal=-1;
StringBuilder strBuff=新的StringBuilder();
试一试{
if(this.command.size()<1)抛出新异常(“Windows命令的长度不能为零”);
ProcessBuilder pb=新的ProcessBuilder(this.command);
Map envVars=pb.environment();
pb.directory();
pb.重定向错误流(真);
process=pb.start();
bis=新的BufferedInputStream(process.getInputStream());
字节[]bArr=新字节[2048];
while(bis.read(bArr)!=-1){
append(新字符串(bArr.trim());
bArr=新字节[2048];
}
exitVal=process.waitFor();
message=strBuff.toString();
}捕获(例外e){
e、 printStackTrace();
System.err.println(e.getMessage());
System.err.println(消息);
}
返回exitVal;
}
公共静态void main(字符串[]args){
WindowsSymlinkUtility foo=新的WindowsSymlinkUtility();
创建符号链接(“%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
java.io.IOException:无法运行程序“mklink”:CreateProcess error=2,系统找不到指定的文件
位于java.lang.ProcessBuilder.start(未知源)
在WindowsSymlinkUtility.runner(WindowsSymlinkUtility.java:113)
在WindowsSymlinkUtility.createSymlink(WindowsSymlinkUtility.java:56)
在WindowsSymlinkUtility.createSymlink(WindowsSymlinkUtility.java:37)
位于WindowsSymlinkUtility.main(WindowsSymlinkUtility.java:134)
原因:java.io.IOException:CreateProcess error=2,系统找不到指定的文件
在java.lang.ProcessImpl.create(本机方法)
位于java.lang.ProcessImpl。(未知源)
位于java.lang.ProcessImpl.start(未知源)
... 还有5个
无法运行程序“mklink”:CreateProcess错误=2,系统找不到指定的文件
无效的
您可能有一些问题:

  • 你为什么这么做?
    • 因为文件系统中的相关文件和文件夹嵌套得很深,所以完整命令的长度远远超过260个字符
  • 符号链接有什么帮助?
    • 我已经做了测试,以确保符号链接允许我“绕过”260个字符的限制
  • 以下是我的问题:

  • 是否有其他方法可以在Java中创建符号链接,以便当命令超过260个字符的限制时Windows可以正常工作
  • 可以用
    SET
    代替
    mklink
  • 即使命令运行超过260个字符,也可以使用
    java.nio.file
    来执行此操作吗

  • 我明白这是一个奇怪的问题。如果有问题,请澄清。

    我对您的程序进行了一些修改,只是为了提供一个工作示例。。。本质上,问题在于没有将变量串联起来,并将它们作为一个参数传递给
    cmd

    一个实施说明:请勿使用
    del
    删除符号链接,否则目标目录中的所有文件都将被删除
    /**
     * @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
    
    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");
        }
    
    }