当前位置: 首页 > 知识库问答 >
问题:

Java理解ByteArrayOutputStream和ByteArrayInputStream

陈哲
2023-03-14

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

我需要澄清我的理解,我需要解释关于使用ByteArrayInputStream和ByteArrayOutputStream...

基于完整的代码:

在capureAudio()方法中,专注于循环,同时

while (running) {
  int count = line.read(buffer, 0, buffer.length);
    if (count > 0) {
      out.write(buffer, 0, count);
    }
}
out.close();

根据定义(检查第64行和第65行):

final TargetDataLine line = (TargetDataLine)
    AudioSystem.getLine(info);

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

在第81行:

      out.write(buffer, 0, count);

out是ByteArrayOutputStream对象。。

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

用我的话说:ByteArrayOutputStream将从quantitycount

在另一边:

在playAudio()方法中。

我可以看到第一行(完整代码的第101行)所有字节都被占用!!!

byte audio[] = out.toByteArray();

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

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

现在在第102行和第103行中

InputStream input = 
    new ByteArrayInputStream(audio);

在行(105到107)上,字节被传递:

  final AudioInputStream ais = 
    new AudioInputStream(input, format, 
    audio.length / format.getFrameSize());

在while循环和近线中聚焦

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行)代表说话人

  final SourceDataLine line = (SourceDataLine)
    AudioSystem.getLine(info);

问题1是:

captureAudio方法中的out将无限地占用字节,但playAudio方法中的input如何精确地占用持续播放所需的字节?

记住:out.toByteArray();取所有字节,但扬声器不会重复发出相同字节的声音...

问题2是:

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

像下一个代码:

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小时)?

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

共有1个答案

容宏逸
2023-03-14

我不熟悉声音API。

但是,假设输入可以无限读取,而输出可以无限馈送,那么您的最后一个代码片段就不能工作,没有什么特别的原因。唯一的问题是一端还是另一端“停滞”(我对声音API的知识缺乏,这就是原因)。

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

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

 类似资料:
  • 主要内容:1 什么是Java ByteArrayOutputStream,2 Java ByteArrayOutputStream的语法,3 Java ByteArrayOutputStream的构造方法,4 Java ByteArrayOutputStream的方法,5 Java ByteArrayOutputStream的例子1 什么是Java ByteArrayOutputStream Java ByteArrayOutputStream 类用于将公共数据写入多个文件。在此流中,数据被写入

  • 我正试图解密一个从Azure存储中下载为ByteArrayOutputStream的文件。 我有一个类型为ByteArrayOutputStream的流。我如何解密它并返回解密的ByteArrayOutputStream? 我尝试过使用CipherOutputStream,但我不确定如何使用它。

  • 本文向大家介绍ByteArrayOutputStream简介和使用_动力节点Java学院整理,包括了ByteArrayOutputStream简介和使用_动力节点Java学院整理的使用技巧和注意事项,需要的朋友参考一下 ByteArrayOutputStream 介绍 ByteArrayOutputStream 是字节数组输出流。它继承于OutputStream。 ByteArrayOutputS

  • ByteArrayOutputStream类流在内存中创建缓冲区,发送到流的所有数据都存储在缓冲区中。 以下是ByteArrayOutputStream类提供的构造函数列表。 Sr.No. 构造函数和描述 1 ByteArrayOutputStream() 此构造函数创建一个具有32字节缓冲区的ByteArrayOutputStream。 2 ByteArrayOutputStream(int a

  • 问题内容: 我在这里遇到了一个很大的问题,我认为这是因为我不太了解如何使用Java提供的API。 我需要写一个和一个到一个 我想到了使用a 来解决用和编写的数据,并且能够将其放入字节数组中,我应该使用method 我知道此类使用Wrapper模式,所以我有两个选择: 要么 但在两种情况下,我都“松散”了一种方法。在第一种情况下,我无法访问该方法,在第二种情况下,我无法访问该方法。 我应该如何一起使

  • 问题内容: 我的磁盘中有40MB的文件,我需要使用字节数组将其“映射”到内存中。 最初,我认为将文件写入ByteArrayOutputStream是最好的方法,但我发现在复制操作期间的某个时刻它会占用约160MB的堆空间。 有人知道不使用三倍于RAM的文件大小的更好方法吗? 更新: 感谢您的回答。我注意到我可以减少内存消耗,告诉ByteArrayOutputStream初始大小比原始文件的大小稍大