Я программирую небольшой графический интерфейс для конвертера файлов в java. Конвертер файлов записывает свой текущий прогресс в stdout. Выглядит так:
Flow_1.wav: 28% complete, ratio=0,447
Я хотел проиллюстрировать это на индикаторе выполнения, поэтому читаю стандартный вывод процесса следующим образом:
ProcessBuilder builder = new ProcessBuilder("...");
builder.redirectErrorStream(true);
Process proc = builder.start();
InputStream stream = proc.getInputStream();
byte[] b = new byte[32];
int length;
while (true) {
length = stream.read(b);
if (length < 0) break;
// processing data
}
Теперь проблема в том, что независимо от того, какой размер массива байтов я выберу, поток читается кусками по 4 КБ. Итак, мой код выполняется до length = stream.read(b);
, а затем на некоторое время блокируется. Как только процесс генерирует выходные данные размером 4 КБ, моя программа получает этот фрагмент и обрабатывает его 32-байтовыми фрагментами. А потом снова ждет следующих 4 КБ.
Я попытался заставить Java использовать буферы меньшего размера, например:
BufferedInputStream stream = new BufferedInputStream(proc.getInputStream(), 32);
Или это:
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()), 32);
Но ничего не изменил.
Затем я нашел это: Источник процесса (около строки 87)
Кажется, что класс Process реализован таким образом, что он передает стандартный вывод процесса в файл. Итак, что на самом деле делает proc.getInputStream();
, это возвращает поток в файл. И этот файл вроде бы записан с буфером 4 КБ.
Кто-нибудь знает какое-то обходное решение для этой ситуации? Я просто хочу мгновенно получить результат процесса.
РЕДАКТИРОВАТЬ: как было предложено Яном Робертсом, я также попытался направить вывод преобразователя в поток stderr, поскольку этот поток, похоже, не заключен в BufferedInputStream
. Еще 4к кусков.
Еще одна интересная вещь: на самом деле я получаю не ровно 4096 байт, а примерно на 5 больше. Боюсь, что сама FileInputStream
буферизирована изначально.
fflush
. Для меня это не имеет смысла! - person R2-D2   schedule 21.02.2013