Обнаружение, если File.Move потребует «Копировать -> Удалить» или просто изменить местоположение в таблице файловой системы - PullRequest
6 голосов
/ 08 сентября 2011

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

Я надеялся, чтоесть способ определить, нужно ли при перемещении файла из «местоположения A» в «местоположение B» выполнять операцию, эквивалентную «File.Copy -> File.Delete», или не будет копировать фактические данные файла, но просто обновите расположение в «таблице основных файлов» и т. п.

Для различных целей я иногда перемещаю большое количество больших файлов.Мне нравится сообщать о прогрессе в пользовательском интерфейсе.

Я понимаю, что когда я вызываю File.Move и перемещаю файл из места на одном диске / разделе в другое, функция фактически должна будет «копировать данные файла -> удалить» между дисками / разделами,Когда он сталкивается с такой ситуацией, я хочу быть в состоянии обнаружить, что это произойдет, поэтому я могу использовать созданный мной код, который будет копировать файл и давать подробные отчеты о ходе выполнения при передаче байтов, чтобы я мог часто обновлять индикаторы выполнения в пользовательском интерфейсе.

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

Используя .NET 4 (C #), можно ли с помощью других средств определить, потребует ли вызов File.Move эквивалентную операцию «копировать -> удалить», или просто обновит таблицу файлов, а не скопируетданные файла?

Редактировать:

Как я отмечаю в комментариях ниже, возможности того, как я думал, что это могло бы быть сделано, заключались бы в обнаружении, еслизаданное местоположение исходного файла и местоположение файла назначения расположены на одном физическом диске и разделе, и если это так, будет ли это означать, что я мог бы точно предвидеть поведение и решать, какие функции вызывать - встроенную функцию File.Move для 'nearмгновенное обновление таблицы файловой системы, которое, как мне кажется, происходит при переходе на тот же диск / часть, или мой более подробный отчет о прогрессе каждые 'x' байтовПользовательский код копирования файла.Скорость передачи файлов может сильно различаться на компьютерах, на которых будут выполняться мои программы, поэтому я хотел бы иметь возможность сообщать подробные сведения о ходе выполнения / текущей скорости передачи, когда это возможно.

Примечание. Программа может использовать сетевые UNC-пути, которые могут бытьиспользование разных физических дисков с одним и тем же корневым путем, например: \\ somename \ shares \ workfolder \ project может находиться на другом физическом диске, чем \\ somename \ shares \ workfoldder \ otherproject.Поэтому мне потребуется метод определения идентификатора раздела или идентификатора физического диска, чтобы определить, находятся ли исходная и целевая папки на одном диске / разделе.

Спасибо

Ответы [ 6 ]

2 голосов
/ 08 сентября 2011

Вы всегда можете P / Invoke для MoveFileWithProgress . Из поверхностного прочтения похоже, что он даст вам более детальный прогресс при копировании, а не перемещении файла.

В качестве альтернативы всегда есть SHFileOperation , который предоставит вам пользовательский интерфейс Windows Explorer и семантику.

1 голос
/ 08 сентября 2011

Я почти уверен, что вы не можете сделать это.

Для начинающих даже в NTFS недостаточно просто посмотреть букву диска для локальных дисков, потому что вы можете смонтировать диск внутрипустая папка на существующем диске .Это означает, что даже если два пути имеют одинаковую букву диска, они все равно могут быть смонтированы на разных дисках.

Чтобы сделать еще один шаг, рассмотрим внешние общие ресурсы, возможно, смонтированные в системе на основе * nix и доступные черезSamba.Символические ссылки * nix не позволяют определить, находятся ли два пути на одном и том же физическом устройстве, рассматривая только пути. Единственный вариант - запросить у удаленного компьютера «существуют ли эти два пути на одном диске?», чтоЯ очень сомневаюсь, что это будет разоблачено.

Я бы просто использовал File.Move и принял бы, что вы не получаете обновления прогресса.В любом случае, написание вашей собственной реализации копии кажется мне «не особо хорошей идеей».

1 голос
/ 08 сентября 2011

Я не думаю, что вы можете обнаружить такую ​​вещь обычным способом, который вам не нужен. Если бы вы могли проверить это, то был бы случай «если» и «еще», поскольку никакие знания не могут быть извлечены из этого (кроме скорости передачи).

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

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

0 голосов
/ 03 февраля 2015

Вы можете P / Invoke функция GetFileInformationByHandle (), которая возвращает серийный номер тома. Если серийный номер тома одинаков для обоих файлов, они находятся на одном и том же томе и копирование и удаление не потребуются.

0 голосов
/ 08 сентября 2011

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

если вы используете полные пути для File.Move, вы можете использовать что-то простое, как:

if(sourcePath[0]!=destinationPath[0])
    //enable transfer speed monitoring

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

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

0 голосов
/ 08 сентября 2011

Хотя это и не на 100% правильно (из-за символических ссылок все выглядит как один большой раздел, в то время как они могут быть разными физическими дисками (из головы в голову, что WHS использует экстенсивно), я бы сказал, для цели индикатора выполненияпри условии, что пребывания в том же разделе (System.IO.Path.GetPathRoot), вероятно, будет достаточно.

...