IOUtils.copy () зависает при копировании большого потока?

1

Я хочу проанализировать содержимое некоторого файла с помощью srcML parser, который является внешней программой Windows. Я делаю это следующим образом:

String command = "src2srcml.exe --language java";
Process proc = Runtime.getRuntime().exec(command);

InputStream fileInput = Files.newInputStream(file)
OutputStream procOutput = proc.getOutputStream();

IOUtils.copy(fileInput, procOutput);

IOUtils.copy() из библиотеки Commons IO 2.4.

Когда мой файл небольшой (несколько КБ), все работает нормально. Однако, когда я пытаюсь скопировать некоторый относительно большой файл (~ 72 КБ), моя программа зависает.

Более того, когда я выполняю парсер "вручную" в cmd:

src2srcml.exe --language Java < BigFile.java

все отлично работает.

Есть идеи, почему это происходит?

  • 0
    Вы уверены, что проблема в размере, а не в самом потоке? Существует метод IOUtils.copyLarge (in, out), но он предназначен для потоков размером более 2 ГБ. Таким образом, 72 КБ не должно быть проблемой.
  • 0
    @luanjot Вы, вероятно, правы. Но тогда, в чем может быть проблема? Кодировка символов?
Показать ещё 5 комментариев
Теги:
stream
apache-commons-io

2 ответа

1
Лучший ответ

Вы должны буферизировать OutputStream:

OutputStream procOutput = proc.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(procOutput);
IOUtils.copy(fileInput, bos);

Более того, почему бы вам просто не перенаправить fileInput как процесс InputStream?

 ProcessBuilder pb = new ProcessBuilder(command);
 pb.redirectInput(file);
 Process proc = pb.start();
 proc.waitFor();
  • 0
    Спасибо, с помощью BufferedOutputStream работал. Я не могу просто перенаправить ввод, потому что на самом деле мой поток ввода является ReplaceInputStream (мне нужно заменить несколько символов перед анализом).
  • 0
    @Kao - использование BufferedOutputStream - это только частичное решение. он снова потерпит неудачу, когда ваш вклад будет достаточно большим. смотри мой ответ.
Показать ещё 8 комментариев
2

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню