我有主文件夾:Directory.Move不工作(文件已經存在)
c:\test
在那裏我有2個文件夾:電影和照片。
照片有三個具有相同結構的文件夾:人物,動物和建築物。我想這樣的代碼:
Directory.Move(@"c:\test\Movies", @"c:\test\Test");
我得到異常:
File already exists
我有主文件夾:Directory.Move不工作(文件已經存在)
c:\test
在那裏我有2個文件夾:電影和照片。
照片有三個具有相同結構的文件夾:人物,動物和建築物。我想這樣的代碼:
Directory.Move(@"c:\test\Movies", @"c:\test\Test");
我得到異常:
File already exists
該方法將遞歸地移動文件夾的內容並覆蓋現有文件。
您應該添加一些異常處理。
編輯:
此方法使用while循環和堆棧實現,而不是遞歸。
public static void MoveDirectory(string source, string target)
{
var stack = new Stack<Folders>();
stack.Push(new Folders(source, target));
while (stack.Count > 0)
{
var folders = stack.Pop();
Directory.CreateDirectory(folders.Target);
foreach (var file in Directory.GetFiles(folders.Source, "*.*"))
{
string targetFile = Path.Combine(folders.Target, Path.GetFileName(file));
if (File.Exists(targetFile)) File.Delete(targetFile);
File.Move(file, targetFile);
}
foreach (var folder in Directory.GetDirectories(folders.Source))
{
stack.Push(new Folders(folder, Path.Combine(folders.Target, Path.GetFileName(folder))));
}
}
Directory.Delete(source, true);
}
public class Folders
{
public string Source { get; private set; }
public string Target { get; private set; }
public Folders(string source, string target)
{
Source = source;
Target = target;
}
}
更新:
這是一個簡單的版本與使用Directory.EnumerateFiles
遞歸而不是使用堆棧。
這隻適用於.net 4或更高版本,使用早期版本的.net更改Directory.EnumerateFiles
至Directory.GetFiles
。
public static void MoveDirectory(string source, string target)
{
var sourcePath = source.TrimEnd('\\', ' ');
var targetPath = target.TrimEnd('\\', ' ');
var files = Directory.EnumerateFiles(sourcePath, "*", SearchOption.AllDirectories)
.GroupBy(s=> Path.GetDirectoryName(s));
foreach (var folder in files)
{
var targetFolder = folder.Key.Replace(sourcePath, targetPath);
Directory.CreateDirectory(targetFolder);
foreach (var file in folder)
{
var targetFile = Path.Combine(targetFolder, Path.GetFileName(file));
if (File.Exists(targetFile)) File.Delete(targetFile);
File.Move(file, targetFile);
}
}
Directory.Delete(source, true);
}
目標目錄不應該已經存在 - 的Directory.Move方法爲您創建的目標目錄。
在將新內容複製到目標文件夾之前刪除目標文件夾是否安全?
Directory.Delete(@"c:\test\test");
Directory.Move(@"c:\test\movies",@"c:\test\test");
不幸的不是... – user278618 2010-03-31 13:10:26
最常見的2個原因Directory.Move
可能會失敗的,如果:
這裏是我的第二個問題簡單的解決方案(覆蓋):
public bool MoveDirectory(string sourceDirName, string destDirName, bool overwrite)
{
if (overwrite && Directory.Exists(destDirName))
{
var needRestore = false;
var tmpDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
try
{
Directory.Move(destDirName, tmpDir);
needRestore = true; // only if fails
Directory.Move(sourceDirName, destDirName);
return true;
}
catch (Exception)
{
if (needRestore)
{
Directory.Move(tmpDir, destDirName);
}
}
finally
{
Directory.Delete(tmpDir, true);
}
}
else
{
Directory.Move(sourceDirName, destDirName); // Can throw an Exception
return true;
}
return false;
}
此代碼存在如果Move(destDirName,tmpDir)失敗,則會在最後刪除(tmpDir)時拋出異常。 – 2015-02-19 11:14:25
C#無法執行此常見Windows操作嗎? – 2017-08-28 13:13:43
ProcessStartInfo p = new ProcessStartInfo("cmd", "/c move \"c:\\test\\Movies\" \"c:\\test\Test\\"");
p.WindowStyle = ProcessWindowStyle.Hidden; //hide mode
Process.Start(p);
一個很好的解決方案,大大提高了相當簡潔的內置一個。 – 2013-04-17 14:41:29
這個方法爲什麼比遞歸更好? – Daniel 2014-01-19 22:40:11
我看到的問題是它在複製過程中鎖定文件並在最後變爲可用Directory.Delete(source,true)將其刪除。 – Daniel 2014-01-19 23:20:45