我不确定这是否是它抛出错误的原因。但对我来说,我在File.Replace
执行驻留在不同目录中的文件的测试失败了。只是想知道其他人是否也是如此。
[TestMethod]
public void TestFileReplaceDifferentDirectory()
{
string FileToReplace = @"c:\tools\file2.txt";
string FileToDelete = @"D:\DropFolder\file0.txt";
string strToWrite;
using (var wtr = File.CreateText(FileToDelete))
{
long ticks = DateTime.Now.Ticks;
strToWrite = string.Join(",", ticks, ticks, ticks);
wtr.WriteLine(strToWrite);
wtr.Flush();
wtr.Close();
}
string BackupFileName = Path.Combine(
Path.GetDirectoryName(FileToReplace),
string.Format("{0}_{1}{2}",
Path.GetFileNameWithoutExtension(FileToReplace),
DateTime.Now.Ticks,
Path.GetExtension(FileToReplace))
);
File.Replace(FileToDelete, FileToReplace, BackupFileName, false);
using (StreamReader rdr = new StreamReader(FileToReplace))
{
string line = rdr.ReadLine();
Assert.AreEqual(strToWrite, line);
}
}
[TestMethod]
public void TestFileReplaceSameDirectory()
{
string FileToReplace = @"c:\tools\file2.txt";
string FileToDelete = @"c:\tools\file0.txt";
string strToWrite;
using (var wtr = File.CreateText(FileToDelete))
{
long ticks = DateTime.Now.Ticks;
strToWrite = string.Join(",", ticks, ticks, ticks);
wtr.WriteLine(strToWrite);
wtr.Flush();
wtr.Close();
}
string BackupFileName = Path.Combine(
Path.GetDirectoryName(FileToReplace),
string.Format("{0}_{1}{2}",
Path.GetFileNameWithoutExtension(FileToReplace),
DateTime.Now.Ticks,
Path.GetExtension(FileToReplace))
);
File.Replace(FileToDelete, FileToReplace, BackupFileName, false);
using (StreamReader rdr = new StreamReader(FileToReplace))
{
string line = rdr.ReadLine();
Assert.AreEqual(strToWrite, line);
}
}
我尝试写入临时文件(使用Path.GetTempFileName()
)并替换D:\DropFolder
中的文件。它没有发生;它扔了一个System.IO.Exception
这是否意味着我唯一的选择是在与FileToReplace
相同的目录中创建一种临时文件并执行此任务?
答案 0 :(得分:1)
这是设计的。使用File.Replace()的目的是能够替换被另一个进程锁定的文件。非常重要的是,如果您只有一次保存珍贵数据,常见于机器关闭或意外程序终止。毋庸置疑,这确实需要一两招,因为Windows坚持要求您不要覆盖锁定的文件。
完全可以,因为操作系统只锁定文件 data ,但不锁定文件的目录条目。换句话说,即使它被锁定,重命名文件也是有效的。底层系统调用与File.Move()相同。
其中有两种不同的操作方式,具体取决于 destFileName 。如果目标路径位于同一驱动器上,则文件系统只需移动目录条目。非常快速且无故障。但是如果在同一个驱动器上不,则无法工作,这也需要移动文件数据。在文件数据被锁定的情况下,这当然很慢并且根本不可能。
因此,传递给File.Replace()的 destinationBackupFileName 参数必须是与 sourceFileName 位于同一驱动器上的路径。移动失败时不执行此操作会导致异常。一般情况下不是很难做到,样板文件是使备份文件名与源文件名完全相同,例如,“.bak”附加到路径上。