Java中如何将MP3文件转换为字节数组?

4

在你说“Google it”之前,我已经尝试过了,找到了一些有趣的文章,但是没有一个有效。

我需要将网站上的mp3文件转换为字节流,以便稍后可以将其保存到本地文件中。

这是我的代码(最重要的部分):

Url url = new Url("someUrl");
URLConnection conn = url.openConnection();
byte[] result = inputStreamToByteArray(conn.getInputStream());
// .... some code here
byteArrayToFile(result, "tmp.mp3");

public byte[] inputStreamToByteArray(InputStream inStream){
    InputStreamReader in = new InputStreamReader(inStream):
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    int next = inStream.read();
    while (next > -1){
        baos.write(next);
        next = in.read();
    }

    byte[] result = baos.toByteArray();
    baos.flush();
    in.close();
    return result;
} 

public void byteArrayToFile(byte[] byteArray, String outFilePath){
    FileOutputStream fos = new FileOutputStream(outFilePath);
    fos.write(byteArray);
    fos.close()
}

代码编译没有错误。

与url的连接是有效的。它发送了正确的响应。

问题出现在转换中。我也通过byteArrayToFile()获得了新文件,并具有适当的长度,但我无法在任何播放器中播放它。它显示长度为00:00,无法播放。

顺便说一下,我想避免使用任何第三方库。但如果没有其他办法...

1个回答

13

顺便提一下,您展示的代码无法编译通过,因为您没有编写必要的异常处理,并且起始应该将inputStream更改为InputStream

这就是问题所在:

InputStreamReader in = new InputStreamReader(inStream):

你正在尝试从二进制流中读取数据,并将其转换为文本。它不是文本。对于像 MP3文件 这样的二进制数据,你不应该使用任何与“Reader”或“Writer”相关的方法。

下面是你的inputStreamToByteArray方法应该像这样(或者使用Guava和它的ByteStreams.toByteArray方法):

public byte[] inputStreamToByteArray(InputStream inStream) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = inStream.read(buffer)) > 0) {
        baos.write(buffer, 0, bytesRead);
    }
    return baos.toByteArray();
}

请注意,我留下了关闭输入流的任务给调用者。通常获取流的人也会关闭它——如果像这个方法一样关闭它本身,可能有点奇怪。你可以这样做,但可能需要在 finally 块中这样操作,这样你就知道即使抛出异常它也会 始终 被关闭。

请注意,如果发生异常,您后面的"写入"代码也不会关闭文件。您应该养成在 finally 块中总是关闭流的习惯。


非常感谢。是的,我有异常处理,只是在我的帖子中没有写出来。顺便问一下,有没有办法获得动态大小的缓冲区?例如,如果我使用列表并在返回时将其转换为数组? - ZolaKt
@ZolaKt:你已经拥有了一个动态大小的缓冲区:ByteArrayOutputStream。8K缓冲区只是作为非常临时的存储而存在。为什么你想要那个是动态大小的呢? - Jon Skeet
我不知道。我只是不喜欢任何“硬编码”的数字 :) 但是你是对的,这是正确的方法。非常感谢。 - ZolaKt
@ZolaKt:在try块之前需要声明变量。你可以在那里初始化它,或者将其设置为null,在try块中初始化,并在finally块中检查是否为null。 - Jon Skeet
“+1” 表示支持这个句子。“您正在尝试从二进制流中读取数据并将其转换为文本格式,但它不是文本。您不应该使用任何与“Reader”或“Writer”类似的工具来处理二进制文件,如 MP3 文件。” - Muzaffer
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接