AiJunRuHua 2008-12-26 15:34
浏览 699
已采纳

请教Runtime.getRuntime().exec(String[] cmdarry)参数的问题

环境windows下,比如我要通过java调用一个程序,程序有一个参数:
程序路径:C:\my dir\myexe.exe
参数:[color=red]param="my parameter"[/color]
调用时:cmd[0] = "C:\my dir\myexe.exe"
cmd[1] = "param=\"my parameter\""
说明:其中整个红色部分是参数,参数中有一个空格,我使用Runtime.getRuntime().exec(String[] cmdarry)以后,发现传进去的参数个数为3,从my后面被截断了,而且引号也不见了,难道不是把cmd[1]整个当作参数吗?疑惑。

  • 写回答

2条回答 默认 最新

  • rednaxelafx 2008-12-26 17:52
    关注

    啊,原来如此。JDK里java.lang.ProcessImpl.start()的实现:
    [quote="JDK 1.6.0_05"][code="java"] // System-dependent portion of ProcessBuilder.start()
    static Process start(String cmdarray[],
    java.util.Map environment,
    String dir,
    boolean redirectErrorStream)
    throws IOException
    {
    String envblock = ProcessEnvironment.toEnvironmentBlock(environment);
    return new ProcessImpl(cmdarray, envblock, dir, redirectErrorStream);
    }

    private long handle = 0;
    private FileDescriptor stdin_fd;
    private FileDescriptor stdout_fd;
    private FileDescriptor stderr_fd;
    private OutputStream stdin_stream;
    private InputStream stdout_stream;
    private InputStream stderr_stream;
    
    private ProcessImpl(String cmd[],
            String envblock,
            String path,
            boolean redirectErrorStream)
    throws IOException
    {
    // Win32 CreateProcess requires cmd[0] to be normalized
    cmd[0] = new File(cmd[0]).getPath();
    
    StringBuilder cmdbuf = new StringBuilder(80);
    for (int i = 0; i < cmd.length; i++) {
            if (i > 0) {
                cmdbuf.append(' ');
            }
        String s = cmd[i];
        if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
            if (s.charAt(0) != '"') {
            cmdbuf.append('"');
            cmdbuf.append(s);
            if (s.endsWith("\\")) {
            cmdbuf.append("\\");
            }
            cmdbuf.append('"');
                } else if (s.endsWith("\"")) {
            /* The argument has already been quoted. */
            cmdbuf.append(s);
        } else {
            /* Unmatched quote for the argument. */
            throw new IllegalArgumentException();
        }
        } else {
            cmdbuf.append(s);
        }
    }
    String cmdstr = cmdbuf.toString();
    
    stdin_fd  = new FileDescriptor();
    stdout_fd = new FileDescriptor();
    stderr_fd = new FileDescriptor();
    
    handle = create(cmdstr, envblock, path, redirectErrorStream,
            stdin_fd, stdout_fd, stderr_fd);
    
    java.security.AccessController.doPrivileged(
        new java.security.PrivilegedAction() {
        public Object run() {
        stdin_stream =
            new BufferedOutputStream(new FileOutputStream(stdin_fd));
        stdout_stream =
            new BufferedInputStream(new FileInputStream(stdout_fd));
        stderr_stream =
            new FileInputStream(stderr_fd);
        return null;
        }
    });
    }[/code][/quote]
    

    可以看到Java标准库自作主张的给带有空白字符的参数的头尾加了引号。也就是说原本给进去的参数是:
    [quote]param="my parameter"[/quote]
    的话,被处理了之后就变成:
    [quote]"param="my parameter""[/quote]
    于是Win32的CreateProcess看到的就是:
    [quote]param=my parameter[/quote]
    (引号会由操作系统决定如何吃掉)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器