Вы не читаете вывод, который генерирует команда copy
.
При порождении дочернего процесса с использованием ProcessBuilder выходные данные, сгенерированные вашим дочерним процессом, записываются в буфер. Если этот буфер не читается, он в итоге заполняется. Когда он заполняется, команда copy
больше не может записывать в него и поэтому блокируется операционной системой. Затем он вынужден ждать, пока в буфере не освободится место, читая из него.
Я запустил ваш код с 20 файлами и обнаружил, что он действительно завис.
Одним из способов решения вашей проблемы является перенаправление вывода с copy
на NUL
. Большая часть выходных данных из copy
представляет собой список всех скопированных файлов, которые, вероятно, вам не слишком важны. Чтобы сделать это перенаправление, измените строку, присваивающую command[2]
, следующее:
command[2] = "copy C:\\output\\html\\*.txt C:\\output\\ >NUL 2>NUL";
Однако, если есть проблема с копированием файлов, вы можете не знать об этом, если будете делать это.
Кроме того, вы можете прочитать выходные данные, которые генерирует команда copy
. Следующий код отправляет его на System.out
, но вы можете легко отправить его в другое место или полностью игнорировать его, если хотите:
String[] command = { "cmd", "/c", "copy C:\\output\\html\\*.txt C:\\output\\" };
ProcessBuilder copyFiles = new ProcessBuilder(command);
copyFiles.redirectErrorStream(true);
p = copyFiles.start();
// The InputStream we get from the Process reads from the standard output
// of the process (and also the standard error, by virtue of the line
// copyFiles.redirectErrorStream(true) ).
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
do {
line = reader.readLine();
if (line != null) { System.out.println(line); }
} while (line != null);
reader.close();
p.waitFor();
Я дал каждому подходу быстрый тест с теми же 20 файлами, и ни один из подходов не завис.
РЕДАКТИРОВАТЬ : Вы также можете попробовать «гибридный» подход, отбрасывая то, что copy
записывает в стандартный вывод (например, список файлов, которые он копирует), но используя второй подход для чтения в чем пишет стандартная ошибка (например, сообщения об ошибках). Для этого вы должны добавить >NUL
, который перенаправляет стандартный вывод copy
на NUL
, но вы не добавите 2>NUL
, так как это перенаправляет стандартную ошибку на NUL
.