Надежная альтернатива File.renameTo () в Windows? - PullRequest
87 голосов
/ 16 июня 2009

Java File.renameTo() проблематично, особенно на Windows, кажется. Как говорится в документации API ,

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

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

Там не должно быть каких-либо блокировок файлов для содержимого перемещаемого каталога, но все же довольно часто renameTo () не выполняет свою работу и возвращает false. (Я просто предполагаю, что, возможно, некоторые блокировки файлов в Windows истекают произвольно.)

В настоящее время у меня есть запасной метод, который использует копирование и удаление, но это отстой, потому что это может занять много времени, в зависимости от размера папки. Я также рассматриваю просто документирование того факта, что пользователь может переместить папку вручную, чтобы избежать ожидания в течение нескольких часов. Но «Правильный путь», очевидно, будет чем-то автоматическим и быстрым.

Итак, мой вопрос: знаете ли вы альтернативный, надежный подход для быстрого перемещения / переименования с помощью Java в Windows , либо с простым JDK, либо с какой-нибудь внешней библиотекой. Или, если вы знаете простой способ обнаружения и снятия любых блокировок файлов для данной папки и всего ее содержимого (возможно, тысяч отдельных файлов), это тоже подойдет.


Редактировать : В данном конкретном случае кажется, что нам удалось использовать только renameTo(), приняв во внимание еще несколько вещей; см. этот ответ .

Ответы [ 14 ]

0 голосов
/ 07 апреля 2012
 File srcFile = new File(origFilename);
 File destFile = new File(newFilename);
 srcFile.renameTo(destFile);

Выше приведен простой код. Я проверил на Windows 7 и работает отлично.

0 голосов
/ 16 июня 2009

Я знаю, что это отстой, но альтернативой является создание сценария bat, который выводит что-то простое, например, "SUCCESS" или "ERROR", вызывает его, ждет его выполнения и затем проверяет его результаты.

Runtime.getRuntime (). Exec ("cmd / c start test.bat");

Эта тема может быть интересной. Также проверьте класс Process, как прочитать вывод консоли другого процесса.

0 голосов
/ 16 июня 2009

Для перемещения / переименования файла вы можете использовать эту функцию:

BOOL WINAPI MoveFile(
  __in  LPCTSTR lpExistingFileName,
  __in  LPCTSTR lpNewFileName
);

Это определяется в kernel32.dll.

0 голосов
/ 16 июня 2009

Вы можете попробовать robocopy . Это не совсем "переименование", но это очень надежно.

Robocopy предназначен для надежного зеркалирования каталогов или деревьев каталогов. Он имеет функции, обеспечивающие копирование всех атрибутов и свойств NTFS, и включает дополнительный код перезапуска для сетевых подключений, которые могут быть нарушены.

...