2011-06-14 35 views
6

我想从波形文件中读取字节到数组中。由于读取的字节数取决于wave文件的大小,因此我创建了一个最大大小为1000000的字节数组。但是这会导致数组末尾出现空值。所以,我想创建一个动态增加的数组,我发现ArrayList是解决方案。但AudioInputStream类的read()函数只将字节读入一个字节数组!我如何将值传递给ArrayList?创建一个ArrayList的字节

+0

你想用这个字节数组做什么?也许你甚至不需要那么大的临时缓冲区。 – pcjuzer 2011-06-14 08:57:25

回答

13

你可以有一个像字节数组:

List<Byte> arrays = new ArrayList<Byte>(); 

要将其转换回阵列

Byte[] soundBytes = arrays.toArray(new Byte[arrays.size()]); 

(然后,你就必须写一个转换器转换Byte[]byte[])。

编辑:您使用List<Byte>错了,我就告诉你如何阅读AudioInputStream简单地ByteArrayOutputStream

AudioInputStream ais = ....; 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
int read; 

while((read = ais.read()) != -1) { 
    baos.write(read); 
} 

byte[] soundBytes = baos.toByteArray(); 

PS如果frameSizeIOException时引发不等于1。因此使用一个字节缓冲器读取数据,像这样:

AudioInputStream ais = ....; 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
byte[] buffer = new byte[1024]; 
int bytesRead = 0; 

while((bytesRead = ais.read(buffer)) != -1) { 
    baos.write(buffer, 0, bytesRead); 
} 

byte[] soundBytes = baos.toByteArray(); 
+0

*****。java:41:找不到符号 symbol:method read(java.util.List ) location:class javax.sound.sampled.AudioInputStream ais.read(buffer ); – 2011-06-14 08:48:50

+0

这不会编译:没有自动/内置的方式来将'List '转换为'byte []'。除此之外,使用'List '' **非常**太空效率低。 – 2011-06-14 08:53:30

+0

@Joachim Sauer,你是对的,我忘了需要从'Byte'转换为字节。修改答案。 – 2011-06-14 08:58:46

17

ArrayList不是解决办法,ByteArrayOutputStream是解决方案。创建ByteArrayOutputStream将字节写入它,然后调用toByteArray()来获取字节。

in = new BufferedInputStream(inputStream, 1024*32); 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 
byte[] dataBuffer = new byte[1024 * 16]; 
int size = 0; 
while ((size = in.read(dataBuffer)) != -1) { 
    out.write(dataBuffer, 0, size); 
} 
byte[] bytes = out.toByteArray(); 
4

像这样的东西应该做的:你的代码应该是什么样子

List<Byte> myBytes = new ArrayList<Byte>(); 

//assuming your javax.sound.sampled.AudioInputStream is called ais 

while(true) { 
    Byte b = ais.read(); 
    if (b != -1) { //read() returns -1 when the end of the stream is reached 
    myBytes.add(b); 
    } else { 
    break; 
    } 
} 

很抱歉,如果代码是有点不对。我有一段时间没有做过Java。

另外,要小心,如果你实现它的while(true)循环:)

编辑:下面是这样做的另一种方式,每次读取多个字节:

int arrayLength = 1024; 
List<Byte> myBytes = new ArrayList<Byte>(); 

while(true) { 

    Byte[] aBytes = new Byte[arrayLength]; 
    int length = ais.read(aBytes); //length is the number of bytes read 

    if (length == -1) { //read() returns -1 when the end of the stream is reached 
    break; //or return if you implement this as a method 
    } else if (length == arrayLength) { //Array is full 
    myBytes.addAll(aBytes); 
    } else { //Array has been filled up to length 

    for (int i = 0; i < length; i++) { 
     myBytes.add(aBytes[i]); 
    } 
    } 
} 

请注意,这两个read()方法都会抛出一个IOException异常 - 处理这个问题留给读者来练习!

+0

他不应该使用'Byte'的'List',并且逐字节读取非常缓慢。 – Kaj 2011-06-14 08:59:06

+0

他想要一个'List'而不是一个数组。另外,我提供了另一个阅读大块的例子。 – 2011-06-14 09:03:40

+0

他想要一个'List',因为他不知道前面的大小。这是正确的解决方案,尽管它不使用“List”。 – 2011-06-14 09:09:26