Runtime.getRuntime().exec() 执行路径或文件中带空格的命令

小伙伴们,大家好。

今天所面对的场景是,我需要通过java来执行linux和windows的复制文件的命令,但是我的文件名中存在了空格,所以就导致了报错。

我的命令是这样的

cp -r /Users/joshua/Documents/wordSpace/G1/target/g1/clientBackupVersion/upload_file/g1_joshua/storage/g1_config.sv_c_custom_html/files/一粒麦子" "和弦简谱.zip /Users/joshua/Documents/g1_upload/g1_joshua/storage/g1_config.sv_c_custom_html/files/一粒麦子" "和弦简谱.zip

但是我当我通过runtime 执行的时候,给我报了这样的一个错误

ERROR>cp: "和弦简谱.zip is not a directory

于是乎,我跟了一下源码,为什么会变成这样,情况是这样的。

着急的小伙伴可以直接跳到标题二去看解决方案,不过我个人还是建议咱们知道下具体实现能更得心应手一点,下次就不至于忘记怎么解决啦。

一、问题原因调查

首先,我们来到入口

在这里,我们点下去,发现他调用了另一个exec方法

 

然后,我们继续往下跟,跟到了有逻辑的一层exec方法

其实我们的命令在这一步就被分割啦,我们走到450行

然后查看447行的cmdarray,发现我们的命令被分割了

接下来,我们来看,他是按着什么规则来进行的分割,我们点446行的new StringTokenizer(command); 就会发现,他是按着下面的五个字符来分割的。

['','\t','\n','\r','\f']

所以,我们如果想让他不被分割,就跳过这一步,那么就直接执行Runtime.java的第450行

 在这里,我们需要知道,他这三个参数的意思,所以我们再往里点一层

我们根据上面的英文注释翻译就可以得知这三个参数的意思了

cmdarray–包含要调用的命令及其参数的数组。

envp–字符串数组,其中每个元素的环境变量设置格式为name=value,如果子流程应该继承当前流程的环境,则为null。

dir–子流程的工作目录,如果子流程应该继承当前流程的工作路径,则为null。

看到这里,我们就发现,我们其实只需要第一个参数,那么我反向跟代码,就是来看这个方法哪里调用过

,我们发现,他有一个方法是只传了第一个参数的,我们点过去看一下

 我们看到了这里,就知道,这个就是我们想要的方法啦。那么我们接下来就开始动手写这样的一个方法来满足我们的需求。

---------------------------------------------------我是分割线------------------------------------------------

二、解决方案

接下来,我们来写一个方法调用这个api

 在这里,我们来看我们要如何去传这个字符串数组

由于我们要执行的是linux的命令

所以我们这样传值

execOSCommons(new String[]{"/bin/sh","-c",command});

在这几个参数里,"/bin/sh"和"-c"是固定的,command就是我们的命令。

最后,我们就会发现,这个文件已经成功的被复制过去啦。

 

如果有什么疑问,或者指教 欢迎加QQ:1318623133

-----------------------------------------   I`am Joshua,may god bless you

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值