Определить размер InputStream - PullRequest
56 голосов
/ 13 июля 2009

Моя текущая ситуация такова: мне нужно прочитать файл и поместить содержимое в InputStream. После этого мне нужно поместить содержимое InputStream в байтовый массив, который требует (насколько мне известно) размер InputStream. Есть идеи?

По запросу я покажу поток ввода, который я создаю из загруженного файла

InputStream uploadedStream = null;
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
java.util.List items = upload.parseRequest(request);      
java.util.Iterator iter = items.iterator();

while (iter.hasNext()) {
    FileItem item = (FileItem) iter.next();
    if (!item.isFormField()) {
        uploadedStream = item.getInputStream();
        //CHANGE uploadedStreambyte = item.get()
    }
}

Запрос является объектом HttpServletRequest, который похож на FileItemFactory, а ServletFileUpload из пакета Apache Commons FileUpload.

Ответы [ 10 ]

37 голосов
/ 14 августа 2013

Это ДЕЙСТВИТЕЛЬНО старая тема, но она по-прежнему всплывала первым, когда я нашел проблему Поэтому я просто хотел добавить это:

InputStream inputStream = conn.getInputStream();
int length = inputStream.available();

работал для меня. И НАМНОГО проще, чем другие ответы здесь.

34 голосов
/ 13 июля 2009

Я прочитал бы в ByteArrayOutputStream , а затем вызвал toByteArray () , чтобы получить результирующий байтовый массив. Вам не нужно определять размер заранее (хотя, возможно, это оптимизация , если вы знаете это . Во многих случаях вы этого не сделаете)

17 голосов
/ 13 июля 2009

Вы не можете определить количество данных в потоке, не читая их; однако вы можете запросить размер файла:

http://java.sun.com/javase/6/docs/api/java/io/File.html#length()

Если это невозможно, вы можете записать байты, прочитанные из входного потока, в ByteArrayOutputStream , который будет увеличиваться по мере необходимости.

12 голосов
/ 13 июля 2009

Я просто хотел добавить, что в Apache Commons IO есть утилиты поддержки потоков для выполнения копирования. (Кстати, что вы имеете в виду, помещая файл во входной поток? Можете ли вы показать нам свой код?)

Edit:

Хорошо, что вы хотите сделать с содержимым предмета? Существует item.get() , который возвращает всю вещь в байтовом массиве.

Edit2

item.getSize() вернет загруженный размер файла .

4 голосов
/ 23 ноября 2018

для InputStream

IoUtils.toByteArray(inputStream).length

Для необязательного

Stream.of(multipartFile.get()).mapToLong(file->file.getSize()).findFirst().getAsLong()
4 голосов
/ 21 марта 2013

вы можете получить размер InputStream, используя getBytes (inputStream) из Utils.java, проверьте следующую ссылку

Получение байтов из входного потока

0 голосов
/ 10 апреля 2019

Если вы знаете, что ваш InputStream является FileInputStream или ByteArrayInputStream, вы можете использовать небольшое отражение, чтобы получить размер потока , не читая все содержимое . Вот пример метода:

static long getInputLength(InputStream inputStream) {
    try {
        if (inputStream instanceof FilterInputStream) {
            FilterInputStream filtered = (FilterInputStream)inputStream;
            Field field = FilterInputStream.class.getDeclaredField("in");
            field.setAccessible(true);
            InputStream internal = (InputStream) field.get(filtered);
            return getInputLength(internal);
        } else if (inputStream instanceof ByteArrayInputStream) {
            ByteArrayInputStream wrapper = (ByteArrayInputStream)inputStream;
            Field field = ByteArrayInputStream.class.getDeclaredField("buf");
            field.setAccessible(true);
            byte[] buffer = (byte[])field.get(wrapper);
            return buffer.length;
        } else if (inputStream instanceof FileInputStream) {
            FileInputStream fileStream = (FileInputStream)inputStream;
            return fileStream.getChannel().size();
        }
    } catch (NoSuchFieldException | IllegalAccessException | IOException exception) {
        // Ignore all errors and just return -1.
    }
    return -1;
}

Это может быть расширено для поддержки дополнительных входных потоков, я уверен.

0 голосов
/ 05 декабря 2017
    try {
        InputStream connInputStream = connection.getInputStream();
    } catch (IOException e) {
        e.printStackTrace();
    }

    int size = connInputStream.available();

int доступно () Возвращает оценку количества байтов, которые можно прочитать (или пропустить) из этого входного потока без блокировки при следующем вызове метода для этого входного потока. Следующим вызовом может быть тот же поток или другой поток. Одно чтение или пропуск этого количества байтов не будет блокировать, но может прочитать или пропустить меньшее количество байтов.

InputStream - Android SDK | Разработчики Android

0 голосов
/ 22 сентября 2017

Если вы явно имеете дело с ByteArrayInputStream, то, вопреки некоторым комментариям на этой странице, вы можете использовать функцию .available(), чтобы получить размер. Просто сделайте это, прежде чем начать читать с него.

Из JavaDocs:

Возвращает количество оставшихся байтов, которые могут быть прочитаны (или пропущены). за) из этого входного потока. Возвращаемое значение: count - pos, которое количество оставшихся байтов для чтения из входного буфера.

https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayInputStream.html#available()

0 голосов
/ 11 ноября 2015

Используйте этот метод, вам просто нужно передать InputStream

public String readIt(InputStream is) {
    if (is != null) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8);

        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line).append("\n");
        }
        is.close();
        return sb.toString();
    }
    return "error: ";
}
...