Java:慎用Runtime.getRuntime().exec

    根据Java JDK的解释,Runtime类封装了该应用程序运行时的环境,而通过getRuntime()方法,可获得当前程序与运行环境关联的对象,通过的对象则可利用Runtime封装的方法利用底层环境对当前程序进行操作。例如Runtime中的exec()方法,就可以实现应用程序调用Linux脚本语言进行相关操作。

    例如,使用此方法删除某文件:

Runtime.getRuntime().exec("rm" + 文件路径);

    但是查看源码发现,此方法是在新开辟的子线程中执行的,所以不适合于某些要求严格的时序流程处理。例如需要使用本地文件时,若发现本地文件被损坏需要删除旧文件并马上执行新的拷贝动作(当然,拷贝前一般会先检查本地文件是否存在,避免经常触发拷贝动作增加性能损耗)。

    public Process exec(String command) throws IOException {
        return exec(command, null, null);
    }

    public Process exec(String command, String[] envp, File dir)
        throws IOException {
        if (command.length() == 0)
            throw new IllegalArgumentException("Empty command");

        StringTokenizer st = new StringTokenizer(command);
        String[] cmdarray = new String[st.countTokens()];
        for (int i = 0; st.hasMoreTokens(); i++)
            cmdarray[i] = st.nextToken();
        return exec(cmdarray, envp, dir);
    }
//在这,利用start()方法开启了一个新的线程
    public Process exec(String[] cmdarray, String[] envp, File dir)
        throws IOException {
        return new ProcessBuilder(cmdarray)
            .environment(envp)
            .directory(dir)
            .start();
    }

    既然说到拷贝,此方法也同样适用于拷贝操作,例如利用如下命令实现快速的数据同步,提高拷贝速度。

Runtime.getRuntime().exec("sync");

    解释sync命令:Linux 系统中欲写入硬盘的资料有的时候会了效率起见,会写到 filesystem buffer 中,这个 buffer 是一块记忆体空间,如果欲写入硬盘的资料存于此 buffer 中,而系统又突然断电的话,那么资料就会流失了,sync 指令会将存于 buffer 中的资料强制写入硬盘中。

    具体拷贝流程如下:

	/**
	 * 拷贝assets 子目录下的apk到指定sd卡路径。  【注意:】需要增加同步锁,避免被多方同事操作
	 *
	 * @param context
	 * @param fileName  文件名称
	 * @param assetsPath  assets子文件夹名称
	 * @param path   目标存储路径
	 * @return
	 */
	public static synchronized boolean copyApkFromAssetsSubFile(Context context, String fileName,String assetsPath,
												   String path) {
		boolean copyIsFinish = false;
		try {
			InputStream is = context.getAssets().open(assetsPath);
			Log.i(TAG, "copyApkFromAssetsSubFile is:"+is.toString());
			File dir = new File(path);
			if (!dir.exists()) {
				dir.mkdirs();
			}
			File file = new File(path, fileName);
			if (!file.exists()) {
				file.createNewFile();
			} else {
				isLocalTTsCopySuccess = true;
				return true; //若文件存在则不拷贝
			}
			FileOutputStream fos = new FileOutputStream(file);
			byte[] temp = new byte[1024];
			int i = 0;
			Log.i(TAG, "copyApkFromAssetsSubFile copping!!!!!");
			while ((i = is.read(temp)) > 0) {
				fos.write(temp, 0, i);
			}
//			fos.flush();
			fos.close();
			is.close();
			copyIsFinish = true;
//流关闭后sync同步,将buffer中的数据强制写入硬盘中
			Runtime.getRuntime().exec("sync");
		} catch (IOException e) {
			Log.e(TAG, "copy failed error is :"+ e.toString());
		}
		Log.i(TAG, "copyApkFromAssetsSubFile copyIsFinish:"+copyIsFinish+"!!!!!");
		return copyIsFinish;
	}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值