Вопрос по c#, file – Mimic File.Move, если место назначения уже существует

7

Из документацииFile.Move:

Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an IOException. You cannot use the Move method to overwrite an existing file.

Короче говоря, вы не можете перезаписать наMoveтак, чтобы облегчить перезапись на Move, я имитирую поведение, выполняяFile.Copy с последующимFile.Delete, Что-то вроде:

if (File.Exists(dstFileName))
{
    // System.IO.File.Move cannot be used to overwrite existing files, so we're going
    // to simulate that behavior with a Copy & Delete.
    File.Copy(procContext.FileName, dstFileName);
    File.Delete(procContext.FileName);
}
else
    File.Move(procContext.FileName, dstFileName);

У меня такой вопрос: есть ли ситуации, которые мне нужно защищать, которые могут привести к удалению исходного файла без его успешного копирования?

Насколько я понимаю из чтения документации, так какFile.Copy не возвращает ничего, что должно выдать исключение, в любом случае, если это не удалось. Кто-нибудь сталкивался с ситуациями, когда это не так?

Не будет ли безопаснее сделать удаление целевого файла, если он существует, с последующим перемещением, как вы делали изначально? Tudor
Но это может быть ответом ... вместо того, чтобы удалять пункт назначения, я должен вместо этого переименовать его. M.Babcock
@ Тюдор - Не обязательно. Если перемещение завершится неудачно, то исходный файл назначения также будет удален, что на самом деле не является ожидаемым поведением. M.Babcock
Конечно, я бы использовалFile.Move если он поддерживает перезапись. Однако, если бы он поддерживал перезапись, я бы ожидалrollback если движение не удалось. Так что, на мой взгляд, будет мало риска. M.Babcock
Но из вашего вопроса я делаю вывод, что если бы перемещение позволило вам перезаписать файл, если он существует, вы бы использовали его вместо копирования + удаления. Итак, я предполагаю, что вы готовы пойти на этот риск? Tudor

Ваш Ответ

5   ответов
0

Проверьте, является ли файл & quot; Target & quot; Exsists. Если нет, скопируйте ваш файл.

Если да, переместите "Target" временно, где вы можете быть уверены, что движение будет успешным. Вы можете создать subdir в Temp с именем auf UUID. Затем скопируйте ваш файл.

4

Трудно смоделировать атомарную операцию, если операционная система не дает вам хороших атомарных операций.Move является атомарным в некоторых, но не во всех файловых системах, но не при перемещении диска на диск.

В случае того же диска,Delete + Move является несколько элегантным (быстрым и безопасным), так как на самом деле не заполняет данные каким-либо образом. Вы могли бы расширить его до

try
{
    Move(dest, tmp);
    Move(src, dest);
    Delete(tmp);
}
catch
{
    try
    {
        Move(tmp, dest);
    }
    catch
    {
    }
    throw;
}

(Это снижает вероятность того, что вы потеряете файл назначения, если, например, у вас нет прав, необходимых для завершения перемещения.)

В случае, если вы не знаете, что это тот же диск, ваше решение достаточно безопасно и достаточно просто. Тем не менее, он копирует данные даже на одном диске, что увеличивает вероятность сбоя питания.

2

Это безопасно. File.Copy либо удастся полностью, либо выкинет. Конечно, удаление может завершиться неудачей, оставив исходный файл как мусор.

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

Во время нормальной работы это безопасно.

5

Правильный способ сделать это будет позвонить

File.Replace(source, destination, copy)

Это делает трюк для меня

Error: User Rate Limit Exceededsocial.msdn.microsoft.com/forums/vstudio/en-US/…
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededthis это чтоrename()Error: User Rate Limit Exceeded
8

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

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

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededArsen Zahray’s answer.
Error: User Rate Limit Exceeded M.Babcock

Похожие вопросы