вход mp3 поток в байтовый массив? - PullRequest
4 голосов
/ 25 ноября 2010

, прежде чем сказать "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 и не будет играть.

Btw. Я хотел бы избежать любых сторонних библиотек. Но если ничего не работает ...

1 Ответ

12 голосов
/ 25 ноября 2010

(Кстати, код, который вы представили , не будет компилироваться без ошибок, кстати. У вас нет требуемой обработки исключений, и inputStream должно быть InputStream, только для начала. )

Это проблема:

InputStreamReader in = new InputStreamReader(inStream):

Вы пытаетесь читать из двоичного потока и преобразовывать его в текст. Это не текст. Вы не должны использовать что-либо, связанное с «Reader» или «Writer» для двоичных данных, таких как файл MP3.

Вот как должен выглядеть ваш 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();
}

Обратите внимание, что я оставил это для вызывающей стороны для очистки входного потока. Обычно тот, кто выбирает поток, также закрывает его - было бы немного странно, если бы такой метод закрывал его сам, IMO. Вы можете сделать это, если хотите, но, вероятно, в блоке finally, чтобы вы знали, что он будет всегда закрыт, даже если было сгенерировано исключение.

Обратите внимание, что ваш "написание" кода позже не закроет файл, если есть исключение. Вы должны иметь привычку всегда закрывать потоки в finally блоках.

...