Java Process:另一个程序正在使用此文件,进程无法访问
Posted isea533
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java Process:另一个程序正在使用此文件,进程无法访问相关的知识,希望对你有一定的参考价值。
最近处理奇怪的问题时,犯了个低级错误,浪费了不少时间,甚至都看了 jdk 底层的 c 代码。
下面这段测试代码是在 Windows 环境运行的(Mac和linux换成 /bin/sh
,-c
后没有问题),你能发现错误在哪里吗?
@Test
public void test() throws Exception
String fileName = "out.log";
File file = new File(fileName);
Process process = new ProcessBuilder(getCommands(fileName)).redirectOutput(file).start();
if(process.isAlive())
process.waitFor();
BufferedReader readStderr = new BufferedReader(new InputStreamReader(process.getErrorStream(), "gbk"));
String line;
while((line = readStderr.readLine()) != null)
System.err.println(line);
readStderr.close();
public List<String> getCommands(String fileName)
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win"))
return Arrays.asList("cmd", "/c", "echo", "hello world", ">", fileName);
else
return Arrays.asList("/bin/sh", "-c", "echo", "hello world", ">", fileName);
Windows环境执行会提示错误 另一个程序正在使用此文件,进程无法访问,错误已经很直接了,但是由于在 Mac 和 Linux 环境没有问题,因此觉得类似的代码在 Windows 上也不存在问题。
debug过程中,修改 getCommands 中的 fileName 时也能成功,有时候修改就不能成功,有时候文件名短的时候能经常性的成功,偶尔会有长文件名的时候也能成功。
错误也很明显了吧?
仍然在迷糊中…
这里新建的文件名,为什么会被占用呢?Windows为什么不把被占用的文件名提示出来?
想看看C代码部分能不能提供有效的信息…
JNIEXPORT jlong JNICALL
Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored,
jstring cmd,
jstring envBlock,
jstring dir,
jlongArray stdHandles,
jboolean redirectErrorStream)
jlong ret = 0;
if (cmd != NULL && stdHandles != NULL)
const jchar *pcmd = (*env)->GetStringChars(env, cmd, NULL);
if (pcmd != NULL)
const jchar *penvBlock = (envBlock != NULL)
? (*env)->GetStringChars(env, envBlock, NULL)
: NULL;
if (!(*env)->ExceptionCheck(env))
const jchar *pdir = (dir != NULL)
? (*env)->GetStringChars(env, dir, NULL)
: NULL;
if (!(*env)->ExceptionCheck(env))
jlong *handles = (*env)->GetLongArrayElements(env, stdHandles, NULL);
if (handles != NULL)
ret = processCreate(
env,
pcmd,
penvBlock,
pdir,
handles,
redirectErrorStream);
(*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0);
if (pdir != NULL)
(*env)->ReleaseStringChars(env, dir, pdir);
if (penvBlock != NULL)
(*env)->ReleaseStringChars(env, envBlock, penvBlock);
(*env)->ReleaseStringChars(env, cmd, pcmd);
return ret;
太长了…跳过…
由于代码不是我写的,所以处理过程中,没有仔细的看过完整的 Process
创建过程,有一瞬间,突然看到了问题的关键:
redirectOutput(file)
//和
">", fileName
上面这个方法已经把输出重定向到 file
了,new File(fileName)
时和命令当前执行的路径是一样的,通过 > fileName
时也是重定向到 fileName
中,所以 另一个程序正在使用此文件,进程无法访问,另一个程序竟然就是自己。
将上面两种方式随便去掉哪一个都可以正常运行。
你在看本文的过程中,有没有更早的发现问题呢?
当 Windows 提示你的操作遇到 “另一个程序正在使用此文件,进程无法访问” 时,这个文件大概率就是你操作的文件,如果找不到其他被使用的地方,可能就是你自己重复使用了同一个文件。
以上是关于Java Process:另一个程序正在使用此文件,进程无法访问的主要内容,如果未能解决你的问题,请参考以下文章
Java Process:另一个程序正在使用此文件,进程无法访问
Java Process:另一个程序正在使用此文件,进程无法访问
Android Studio 另一个程序正在使用此文件,进程无法访问
错误记录Flutter 混合开发报错 ( java.nio.file.FileSystemException: xxx/R.jar: 另一个程序正在使用此文件,进程无法访问。 )