【发布时间】:2023-03-21 03:03:01
【问题描述】:
所以我下面的代码sn-p(concat方法)主要尝试做两件事:
- 将从源文件列表中读取的多个 AudioInputStream 连接到一个最终的长流中
-
将该流写入目标 WAV 文件
public static void concat(ArrayList<String> sourceFiles, String targetFile) { AudioInputStream targetBuilder = null; String file; AudioInputStream nextSource; for (int i = 0; i < sourceFiles.size(); i++) { file = sourceFiles.get(i); if(targetBuilder == null) { targetBuilder = AudioSystem.getAudioInputStream(new File(file)); continue; } nextSource = AudioSystem.getAudioInputStream(new File(file)); AudioInputStream appendedFiles = new AudioInputStream( new SequenceInputStream(targetBuilder, nextSource), targetBuilder.getFormat(), targetBuilder.getFrameLength() + nextSource.getFrameLength()); targetBuilder = appendedFiles; nextSource.close(); } AudioSystem.write(targetBuilder, AudioFileFormat.Type.WAVE, new File(targetFile)); targetBuilder.close(); }
这个想法是从这个线程借来的:Join two WAV files from Java。现在的问题是在连续多次执行这个sn-p之后,最终它会在AudioSystem.write()行的“stream closed”上抛出IO Exception。堆栈跟踪如下所示:
java.io.IOException: Stream Closed
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:272)
at javax.sound.sampled.AudioInputStream.read(AudioInputStream.java:292)
at java.io.SequenceInputStream.read(SequenceInputStream.java:208)
at java.io.SequenceInputStream.read(SequenceInputStream.java:211)
at javax.sound.sampled.AudioInputStream.read(AudioInputStream.java:292)
at java.io.SequenceInputStream.read(SequenceInputStream.java:208)
at javax.sound.sampled.AudioInputStream.read(AudioInputStream.java:292)
......//with the exact same two lines repeating lots of times
at java.io.SequenceInputStream.read(SequenceInputStream.java:208)
at javax.sound.sampled.AudioInputStream.read(AudioInputStream.java:292)
at com.sun.media.sound.SunFileWriter$NoCloseInputStream.read(SunFileWriter.java:198)
at java.io.SequenceInputStream.read(SequenceInputStream.java:208)
at java.io.InputStream.read(InputStream.java:101)
at com.sun.media.sound.WaveFileWriter.writeWaveFile(WaveFileWriter.java:239)
at com.sun.media.sound.WaveFileWriter.write(WaveFileWriter.java:137)
at javax.sound.sampled.AudioSystem.write(AudioSystem.java:1354)
at com.mycompany.mypackage.AudioUtils.concat(AudioUtils.java:324)
......
所以在我看来,程序仍然尝试从 AudioInputStream 读取更多字节到文件,但在某些时候流 (targetBuilder) 只是自行关闭。这对我来说没有意义,因为我只在我的 AudioSystem.write() 方法之后关闭了这个流。
现在,如果我真的在 for 循环中评论这一行:
//nextSource.close();
这个流关闭异常似乎消失了,替换为“FilesNotFoundException:打开的文件太多”,这对我来说很有意义,因为在循环的每次迭代中,我都会创建一个新的 AudioInputStream 并分配对 nextSource 的引用,但是如果我从不关闭它,最终我用完了打开的文件描述符。
但我不明白的是,关闭此 nextSource 流会以任何方式影响 targetBuilder 流的行为吗?如果我关闭 nextSource 流,为什么该流会突然关闭? (我假设两者之间有联系,如果我错了,请纠正我。
谢谢!
【问题讨论】:
标签: java audio stream ioexception