Java - Progress Bar при загрузке с FileUtils
Я пытаюсь загрузить большой файл с URL с помощью библиотеки Apache commons.io. Это мой код:
InputStream stream = new URL(CLIENT_URL).openStream();
ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(null, "Downloading...", stream);
ProgressMonitor pm = pmis.getProgressMonitor();
pm.setMillisToDecideToPopup(0);
pm.setMillisToPopup(0);
FileUtils.copyInputStreamToFile(pmis, new File(LATEST_FILENAME));
pmis.close();
stream.close();
Но это не показывает всплывающее окно. Или, если честно, всплывающие окна появляются и исчезают только на миллисекунд, а загрузка занимает около 10 секунд.
1 ответ
Универсальный InputStream
не предоставляет информацию о текущей позиции или общей длине для внешнего мира. Смотрите InputStreamavailiable()
это не общий размер InputStream
и нет такой вещи, как получить текущую позицию или получить общий размер. Вы также можете читать только фрагменты / части потока, даже индикатор выполнения сможет определить общую длину потока, он не будет знать, что вы собираетесь читать, например, 512 байт.
ProcessMonitorInputStream
украшает предоставленный InputStream
и обновляет индикатор выполнения диалогового окна во время операции чтения. По умолчанию ProgressMonitorInputStream
использование available
из пройденного InputStream
инициализировать максимальное значение ProgressMonitor
, Значение может быть правильным для некоторых InputStreams
но не особенно когда вы передаете данные по сети.
available()
возвращает оценку количества байтов, которые могут быть прочитаны (или пропущены) из этого входного потока без блокировки при следующем вызове метода для этого входного потока.
Это начальное максимальное значение также является причиной, по которой вы иногда видите диалоговое окно. Диалог закрывается автоматически после достижения максимального значения индикатора выполнения. Для того, чтобы показать что-нибудь полезное, вы должны дать ProgressMonitor
некоторые подсказки о начальной позиции и конечной позиции в виде setMinimum
а также setMaximum
,
// using a File just for demonstration / testing
File f = new File("a");
try (InputStream stream = new FileInputStream(f)) {
ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(null, "Downloading...", stream);
int downloadSize = f.length();
ProgressMonitor pm = pmis.getProgressMonitor();
pm.setMillisToDecideToPopup(0);
pm.setMillisToPopup(0);
// tell the progress bar that we start at the beginning of the stream
pm.setMinimum(0);
// tell the progress bar the total number of bytes we are going to read.
pm.setMaximum(downloadSize);
copyInputStreamToFile(pmis, new File("/tmp/b"));
}