首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java理解ByteArrayOutputStream和ByteArrayInputStream

Java理解ByteArrayOutputStream和ByteArrayInputStream
EN

Stack Overflow用户
提问于 2016-02-20 02:42:47
回答 1查看 2K关注 0票数 0

我读过这篇文章:http://www.java-tips.org/java-se-tips-100019/120-javax-sound/917-capturing-audio-with-java-sound-api.html,我不想写所有的代码,从前一篇文章.

我需要澄清我的理解,我需要解释ByteArrayInputStream和ByteArrayOutputStream的用途.

根据完整的代码:

captureAudio()方法中,将注意力集中在循环上

代码语言:javascript
复制
while (running) {
  int count = line.read(buffer, 0, buffer.length);
    if (count > 0) {
      out.write(buffer, 0, count);
    }
}
out.close();

根据定义(请参阅第64和65行):

代码语言:javascript
复制
final TargetDataLine line = (TargetDataLine)
    AudioSystem.getLine(info);

在第79行:该行是麦克风和//从数据线的输入缓冲区读取音频数据。换句话说,从麦克风传入的字节被定位或存储在字节buffer中。

在第81行:

代码语言:javascript
复制
      out.write(buffer, 0, count);

out是一个ByteArrayOutputStream对象。

Java的ByteArrayOutputStream类允许您捕获写入数组中的流的数据。将数据写入ByteArrayOutputStream,完成后调用ByteArrayOutputStream的方法toByteArray()以获得字节数组中的所有写入数据。当数据被写入缓冲区时,缓冲区会自动增长。

用我的话说:ByteArrayOutputStream将从count数量中定义的缓冲区中获取字节。

在另一边:

playAudio()方法中。

我可以看到,第一行(完整代码的第101行)所有字节都被取走了!

代码语言:javascript
复制
byte audio[] = out.toByteArray();

https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html#toByteArray()

创建新分配的字节数组。它的大小是此输出流的当前大小,并且缓冲区的有效内容已经复制到其中。

现在行(102和103)

代码语言:javascript
复制
InputStream input = 
    new ByteArrayInputStream(audio);

在行(105到107 )上,字节通过:

代码语言:javascript
复制
  final AudioInputStream ais = 
    new AudioInputStream(input, format, 
    audio.length / format.getFrameSize());

在时间环和近线中聚焦

代码语言:javascript
复制
int count;
while ((count = ais.read(
  buffer, 0, buffer.length)) != -1) {
    if (count > 0) {
      line.write(buffer, 0, count);
    }
  }
line.drain();
line.close();

字节来自ais

而这一行(第110和111行)代表的是扬声器。

代码语言:javascript
复制
  final SourceDataLine line = (SourceDataLine)
    AudioSystem.getLine(info);

问题1是:

来自captureAudio方法的out将无限地占用字节,但是来自playAudio方法的input是如何准确地获得一致发音所需的字节的呢?

记住:out.toByteArray();接收所有字节,但是扬声器听起来不会重复相同的字节.

问题2是:

我可以处理这种情况从麦克风(TargetDataLine)读取和写扬声器(SourceDataLine),而不使用这两个对象(ByteArrayOutputStream和ByteArrayInputStream),如相关的文章?

就像下一个代码:

代码语言:javascript
复制
while (running) {
  int count = microphone.read(buffer, 0, buffer.length);
    if (count > 0) {
      speaker.write(buffer, 0, count);
    }
}
speaker.drain();
speaker.close();

问题3是:

我如何实现一个复读机(从麦克风捕捉声音,并在扬声器上播放,无限,1或2个小时)?

注意:不用担心存储问题,内存中的字节(不存储在文件中),没有回放延迟。

EN

回答 1

Stack Overflow用户

发布于 2016-02-20 22:11:50

我不熟悉声音API。

但是,假设输入可以无休止地读取,而输出可以无休止地提供,您的最后一个代码段不应该工作,这没有什么特别的原因。唯一的问题是,到底是一端还是另一端“停滞”(这里,我对声音API缺乏了解来玩)。

如果输出端因某种原因中断,则输入端可能会溢出一些内部缓冲区,从而丢失信息。如果输入停止,那就不是什么问题了。我不知道这是否是声音API的一个实际问题。相反,如果出现两个线程(或使用异步I/O),一个线程管理输入,另一个线程管理输出,则输入端将使程序有机会使用您的语义而不是API语义来缓存传入的数据,而输出通道则处于停滞状态。

ByteArrayStreams的问题仅仅是填充和每个扩展字节数组的机制,而不是自己管理它,并且,类似地,将流语义添加到底层字节数组(它具有各种有用的功能)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35518494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档