有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

下载后无法通过进程运行程序(Java)

下载程序(NirCmd)后,如下所示:

        URL website = new URL(
                "https://copy.com/Q4qch6FBPZkrclxG/nircmd.exe?download=1");
        ReadableByteChannel rbc = Channels.newChannel(website.openStream());
        FileOutputStream fos = new FileOutputStream("nircmd.exe");

        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);

然后像这样运行它:

Process process = Runtime.getRuntime().exec("nircmd.exe speak text Hi");

但它抛出了一个例外:

java.io.IOException: Cannot run program "nircmd.exe": CreateProcess error=32, The process cannot access the file because it is being used by another process
at java.lang.ProcessBuilder.start(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at Main.main(Main.java:18)

Caused by: java.io.IOException: CreateProcess error=32, The process cannot access the file because it is being used by another process
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(Unknown Source)
at java.lang.ProcessImpl.start(Unknown Source)
... 5 more

共 (3) 个答案

  1. # 1 楼答案

    修好了!我是这样做的:

    当它运行时:

        URL website = new URL(
                "https://copy.com/Q4qch6FBPZkrclxG/nircmd.exe?download=1");
        ReadableByteChannel rbc = Channels.newChannel(website.openStream());
        FileOutputStream fos = new FileOutputStream("nircmd.exe");
    
        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
    

    它需要一个:

    if(new File("nircmd.exe").exists())  {
        ... code here
    }
    
  2. # 2 楼答案

    关闭输出流。否则(至少在Windows中),它会在一段不确定的时间内对底层文件资源保持独占写入锁定

    应该通过以确定的方式调用^{}来处理,以避免这个问题

    如果close未被调用则流将“在将来某个不确定的时间关闭,当/如果终结器运行或程序退出”。正如所见,这种不确定性行为可能会导致错误和不稳定的行为

    为了简化操作,因为正确包装和调用close方法非常繁琐,可以使用try-with-resources语句:

    try (
      ReadableByteChannel rbc = Channels.newChannel(website.openStream());
      FileOutputStream fos = new FileOutputStream("nircmd.exe"))
    ) {
        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
    }
    
    // Now nircmd.exe can be opened because fos.close()
    // is GUARANTEED to have been called (by try-with-resources)
    // and the underlying file is no longer [exclusively] opened.
    

    虽然关闭阅读频道并不重要(在本例中),但出于傲慢、一致性和实践的考虑,应该关闭阅读频道


    增编:

    添加一个随机的File.exists检查实际上并不能“修复”问题-,尽管它可能会触发一个副作用,使它“看起来有效”,但它是不可靠的代码

    文件确实存在,或者读取“[确实存在的文件]正被另一个进程使用”的异常将不同。问题是当前进程仍在非共享模式下打开


    Is it necessary to close each nested OutputStream and Writer separately?是一个相当好的概览,应该是相关问题的良好起点

  3. # 3 楼答案

    可以使用java库“Apache Commons IO”来完成

    我的简单代码:

    URL url = new URL("https://copy.com/Q4qch6FBPZkrclxG/nircmd.exe?download=1");
    InputStream input = url.openStream();
    String exef= "nircmd.exe";
    FileOutputStream output = new FileOutputStream(exef);
    IOUtils.copy(input, output);
    

    类“IOUtils”是commons IO jar中用于IO流操作的常用工具