ProcessBuilder不会停止
我试图通过使用Linux下的ProcessBuilder类将mp3文件解码为wav文件。 由于某种原因,该过程不会停止,因此我必须手动取消它。
有人可以给我一个暗示。 我认为引用的代码很容易重现:
import java.io.*; public class Test { public static void main(String[] args) { try { Process lameProcess = new ProcessBuilder("lame", "--decode", "test.mp3", "-").start(); InputStream is = lameProcess.getInputStream(); FileOutputStream fileOutput = new FileOutputStream("test.wav"); DataOutputStream dataOutput = new DataOutputStream(fileOutput); byte[] buf = new byte[32 * 1024]; int nRead = 0; int counter = 0; while((nRead = is.read(buf)) != -1) { dataOutput.write(buf, 0, buf.length); } is.close(); fileOutput.close(); } catch (Exception e) { e.printStackTrace(); } } }
输出jstack
"main" prio=10 tid=0x0000000002588800 nid=0x247a runnable [0x00007f17e2761000] java.lang.Thread.State: RUNNABLE at java.io.FileInputStream.readBytes(Native Method) at java.io.FileInputStream.read(FileInputStream.java:236) at java.io.BufferedInputStream.fill(BufferedInputStream.java:235) at java.io.BufferedInputStream.read1(BufferedInputStream.java:275) at java.io.BufferedInputStream.read(BufferedInputStream.java:334) - locked (a java.io.BufferedInputStream) at java.io.FilterInputStream.read(FilterInputStream.java:107) at Test.main(Test.java:17)
您需要排除进程的输出(通过getInputStream()
)和错误(通过getErrorStream()
)流,否则它可能会阻塞。
引用流程文档 :
由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此无法及时写入输入流或读取子进程的输出流可能导致子进程阻塞,甚至死锁。
(适用于错误和输出流)
您可能需要在不同的线程中排出每个流,因为每个流都可能在没有数据时阻塞。
使用像LAMEOnJ这样的LAME Java包装器可能要容易得多 。 这样你就可以避免产生进程,你只需要与lame进行交互,就像它是一个Java库一样。