代码之家  ›  专栏  ›  技术社区  ›  ZolaKt

java mp3输入流到字节数组?

  •  4
  • ZolaKt  · 技术社区  · 14 年前

    在你说“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的连接有效。它发送正确的响应。

    问题出在转换的某个地方。 在bytearrytofile()之后,我还在磁盘上以适当的长度获取新文件,但是我不能在任何播放器中播放它。上面说长度是00:00,不会播放。

    顺便说一下,我想避免任何第三方的lib。但如果没有别的办法。。。

    1 回复  |  直到 14 年前
        1
  •  12
  •   Jon Skeet    14 年前

    (你提供的代码 不会 顺便说一下,编译时没有错误。您没有必需的异常处理,并且 inputStream 应该是 InputStream ,只是作为开始。)

    这就是问题所在:

    InputStreamReader in = new InputStreamReader(inStream):
    

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

    这是你的 inputStreamToByteArray 方法应该看起来像(或使用 Guava 以及 ByteStreams.toByteArray method ):

    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();
    }
    

    注意我把它留给了 来电者 清理输入流。通常,获取流的人也会关闭它——对于这样的方法来说,关闭流本身会有点奇怪,IMO finally 封锁你就会知道 总是 即使抛出异常也要关闭。

    请注意,如果有异常,以后的“编写”代码也不会关闭文件。你应该养成一个习惯,总是把小溪关上 最后 阻碍。