Как определить, будет ли файл перемещен логически или физически
-
09-09-2019 - |
Вопрос
Факты:
Когда файл перемещается, есть две возможности:
- Исходный и конечный файлы находятся в одном разделе, и обновляется только индекс файловой системы
- Источник и место назначения находятся в двух разных файловых системах, и файл необходимо перемещать байт за байтом.(он же копирование при перемещении)
Этот вопрос:
Как я могу определить , будет ли файл перемещен логически или физически ?
Я передаю большие файлы (700+ мегабайт) и буду использовать различное поведение для каждой ситуации.
Редактировать:
Я уже закодировал диалоговое окно перемещения файла с рабочим потоком, который выполняет блокирующий вызов ввода-вывода для копирования файла на мегабайт за раз.Он предоставляет пользователю информацию, такую как приблизительная оценка оставшегося времени и скорости передачи.
Проблема в том, что:как мне узнать , можно ли переместить файл логически , прежде чем пытаться переместить его физически ?
Решение 2
Ладно, я кое-чем занимаюсь :)
Используя ЮНА Я способен вызовите Win32 API (и * nix API тоже) из java.
Я пытался дозвониться GetFileInformationByHandle
и действительно получил результат, НО dwVolumeSerialNumber
атрибут всегда равен 0 (пробовал с моим C:и D:привод)
Затем я увидел эту функцию в MSDN: MoveFileEx
.Когда параметру флага присвоено значение 0, функция копирования при перемещении будет отключена. И ЭТО РАБОТАЕТ !!!!
Поэтому я просто позвоню
if (!Kernel32.INSTANCE.MoveFileEx(source.getAbsolutePath(), destination.getAbsolutePath(), 0)) {
System.out.println("logical move failed");
}
Вот код, который нужно вставить в Kernel32.java
интерфейс (этот файл можно найти в пакете src.zip в разделе загрузки на ЮНА сайт):
boolean MoveFileEx(String lpExistingFileName, String lpNewFileName, int dwFlags);
int MOVEFILE_REPLACE_EXISTING = 0x01;
int MOVEFILE_COPY_ALLOWED = 0x02;
int MOVEFILE_CREATE_HARDLINK = 0x04;
int MOVEFILE_WRITE_THROUGH = 0x08;
int MOVEFILE_DELAY_UNTIL_REBOOT = 0x10;
int MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20;
Другие советы
В Linux или других *nices вызовите stat()
в исходном и целевом каталогах и сравните их st_dev
ценности.Если они совпадают, может быть выполнено логическое перемещение, в противном случае необходимо выполнить физическое копирование + удаление.
В Windows вы можете вызвать GetFileInformationByHandle()
на дескрипторах к двум каталогам и сравните их dwVolumeSerialNumber
ценности.Обратите внимание, что для этого требуется Windows 2000 или более поздняя версия.
Я вижу, вы используете Java - должен быть какой-то портал, через который вы можете получить доступ к этой информации на уровне ОС (возможно, JNI?)