Конструктор SequenceInputStream выбирает только первый входной поток и игнорирует остальные

Я использую SequenceInputStream для объединения нескольких потоков в один поток. Я на JDK8. Ниже приведен код.

private InputStream mergeInputStreams(final Map<String, InputStream> fileAssets, final JSONObject json) throws Exception {

    final List<InputStream> listStreams = new ArrayList<InputStream>();

    listStreams.add(stringToStream(HEADER));
    addToList(json, listStreams);

    listStreams.add(stringToStream(HEADER_2));
    addToList(fileAssets.get(FILE_2), listStreams, true);

    listStreams.add(stringToStream(HEADER_3));
    addToList(fileAssets.get(FILE_3), listStreams, false);

    return new SequenceInputStream(Collections.enumeration(listStreams));
}

private void addToList(final InputStream inputStream, List<InputStream> listStreams, final boolean delimiter) throws Exception {
    final byte[] input = byteArrayFromStream(inputStream);
    listStreams.add(intToStream(input.length));
    listStreams.add(new ByteArrayInputStream(input));
    if (delimiter) {
        listStreams.add(stringToStream("\n"));
    }
}

private void addToList(final JSONObject json, final List<InputStream> listStreams) throws Exception {
    final String jsonString = json.toString();
    listStreams.add(intToStream(jsonString.length()));
    listStreams.add(stringToStream(jsonString));
}

У меня проблема в том, что я всегда получаю первый поток от объекта SequenceInputStream, т.е. я просто получаю строку HEADER. Я пробовал несколько вариантов, в том числе

new SequenceInputStream(listStreams.get(9), listStreams.get(9)); 

В приведенном выше примере я пытаюсь объединить один и тот же вход дважды. Тем не менее, я все еще получаю 9-й входной поток только один раз.

Я проверил, что я получаю несколько потоков в перечислении.

Было бы здорово, если бы кто-то мог помочь мне понять, что здесь происходит.

2 ответа

Он будет читать первый поток до конца потока, затем второй и так далее. Возможно, это не то, что вы ожидаете? Это также означает, что вы не можете предоставить один и тот же поток дважды, так как он будет полностью прочитан при первом использовании.

Я не вижу, что конструкторы связаны с этим.

Вот что мы имеем:

  1. Создайте объект sequenceinputstream 's' из потоков 'n'
  2. загрузить 's' на S3 с помощью внешней библиотеки. lib.uploadToS3(ы)

Проблема: сторонний вызов uploadToS3(stream) из библиотеки использовал stream.available () для инициализации массива буферов, заполняя его из потока и загружая его.

Похоже, что SequenceInputStream.available () ( http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/io/SequenceInputStream.java) возвращает доступные () из текущий поток повторяется. например, в контексте lib.uploadToS3 (), он использовал available () из самого первого потока в последовательности.

Что мы исправили: Мы исправили библиотеку для использования IOUtils.copy() вместо написания кода копирования, который полагается на available ().

Другие вопросы по тегам