根据文档,TargetDataLine.read()
是一种阻塞方法,即调用read()
块,直到它具有可读取的请求字节数。但是,如果数据行已关闭,已停止,已耗尽或已刷新,则会立即返回。
我有一个实时应用程序,可以无限期地从音频接口读取和处理数据。我的音频设备通过USB连接与计算机连接。如果在读取数据时拔下USB连接,我的应用程序将无限期地阻止read()
方法而不会引发任何异常。是预期的行为还是有任何方法可以检测到物理连接已被删除?
更新1: Bellow代码段可以重现此问题。
public class TestSoundCapture {
public TestSoundCapture() {
new Thread(new CaptureBack()).start();
}
public static void main(String[] args) {
new TestSoundCapture();
}
private class CaptureBack implements Runnable {
public CaptureBack() { }
@Override
public void run() {
int numBytesRead = 0;
byte[] shortBuffer = new byte[2048];
final TargetDataLine dataLine = getDataLine();
dataLine.start(); // begin audio capture.
while (true) {
try {
numBytesRead = dataLine.read(shortBuffer, 0, shortBuffer.length);
Thread.sleep(20);
}
catch (Exception e) {
System.out.println("Exception: "+e.toString());
break;
}
System.out.println("Store "+numBytesRead+" in a circular buffer");
}
// stop and close the line.
dataLine.stop();
dataLine.close();
System.out.println("Capturing Finished!");
}
private TargetDataLine getDataLine() {
AudioFormat aFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100.0F, 16, 2, 4, 44100.0F, false);
TargetDataLine line = null;
DataLine.Info info = new DataLine.Info(TargetDataLine.class, aFormat);
try {
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(aFormat);
}
catch (LineUnavailableException ex) {
}
return line;
}
}
}
当音频设备断开连接时,后台线程卡在read()
方法上。
更新2:即使我认为我不喜欢它,在尝试阅读之前,可能还有一种方法是检查available()
。具体来说,调用read()
iff available()
返回更多或相等数量的字节,我想读取。
int counter = 0; // counts number of consecutive failed attempt.
final int buffSize = 2048;
while (true) {
if (counter > 3) break; // no data available on the line.
Thread.sleep(20);
if (dataLine.available() < buffSize) {
counter++;
continue;
}
else {
numBytesRead = dataLine.read(shortBuffer, 0, buffSize);
counter = 0;
}
System.out.println("Store "+numBytesRead+" in a circular buffer");
}