- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
Winforms 程序需要将一些运行时信息保存到 XML 文件中。该文件有时可能有几百 KB 的大小。在 Beta 测试期间,我们发现一些用户会毫不犹豫地终止进程,看似随意,偶尔会导致文件写入一半并因此损坏。
因此,我们更改了算法以保存到临时文件,然后删除真实文件并进行 move 。
我们的代码目前看起来是这样的..
private void Save()
{
XmlTextWriter streamWriter = null;
try
{
streamWriter = new XmlTextWriter(xmlTempFilePath, System.Text.Encoding.UTF8);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyCollection));
xmlSerializer.Serialize(streamWriter, myCollection);
if (streamWriter != null)
streamWriter.Close();
// Delete the original file
System.IO.File.Delete(xmlFilePath);
// Do a move over the top of the original file
System.IO.File.Move(xmlTempFilePath, xmlFilePath);
}
catch (System.Exception ex)
{
throw new InvalidOperationException("Could not save the xml file.", ex);
}
finally
{
if (streamWriter != null)
streamWriter.Close();
}
}
这几乎在所有时间都适用于实验室和生产。该程序在 12 台计算机上运行,这段代码平均每 5 分钟调用一次。大约一天一次或两次,我们会收到此异常:
System.InvalidOperationException:
Could not save the xml file.
---> System.IO.IOException: Cannot create a file when that file already exists.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.__Error.WinIOError()
at System.IO.File.Move(String sourceFileName, String destFileName)
at MyApp.MyNamespace.InternalSave()
就好像在Move发出之前Delete实际上并没有下达到硬盘上。
这发生在 Win7 机器上。
几个问题:是否有一些Flush()
的概念可以用于整个磁盘操作系统?这是我的代码、.net、操作系统或其他东西的错误吗?我应该加入一些 Thread.Sleep(x)
吗?也许我应该做一个 File.Copy(src, dest, true)
?我应该写下面的代码吗? (但它看起来很傻。)
while (System.IO.File.Exists(xmlFilePath))
{
System.IO.File.Delete(xmlFilePath);
}
// Do a move over the top of the main file
bool done = false;
while (!done)
{
try
{
System.IO.File.Move(xmlTempFilePath, xmlFilePath);
done = true;
}
catch (System.IO.IOException)
{
// let it loop
}
}
有人见过这个吗?
最佳答案
您永远不能假设您可以删除文件并在多用户多任务操作系统上删除它。除了另一个应用程序或用户自己对文件感兴趣之外,您还可以运行对文件感兴趣的服务。病毒扫描程序和搜索索引器是典型的麻烦制造者。
此类程序打开文件并尝试通过指定删除共享访问权限来尽量减少影响。这在 .NET 中也可用,它是 FileShare.Delete 选项。有了这个选项,Windows 允许进程删除文件,即使它是打开的。它在内部被标记为“删除待处理”。该文件实际上并没有从文件系统中删除,它在 File.Delete 调用之后仍然存在。之后尝试打开文件的任何人都会收到拒绝访问错误。在文件对象的最后一个句柄关闭之前,文件实际上并没有被删除。
您可能会看到这是标题,这解释了为什么 File.Delete 成功但 File.Move 失败。您需要做的是 File.Move 文件,使其具有不同的名称。 然后重命名新文件,然后删除原来的文件。您要做的第一件事是删除一个可能的重命名名称的杂散副本,它可能是由于电源故障而遗留下来的。
总结:
第 5 步的失败并不重要。
关于c# - System.IO.File.Delete()/System.IO.File.Move() 有时不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6466940/
C++ 中的标准“映射”容器允许您插入右值: T x; std::map m; // m[1]; // populate "1" auto it = m.insert(std::make_pair(
我们知道 std::move does not actually move anything .它只是将左值引用 (&) 转换为右值引用 (&&)。 那么在下面的例子中,拷贝构造函数是如何被调用的呢?
http://en.cppreference.com/w/cpp/language/rule_of_three 几个月前我开始使用 c++11并观看了五人规则。 所以..我开始将复制构造函数/复制赋值
这个问题在这里已经有了答案: In what scenarios should I expect to explicitly need to implement a move constructor
我有一个类似于下面的对象,我正在尝试为它实现一个 move 构造函数,这样你就可以为 std::vector 插入一个. struct Mesh { std::vector vPoint
这个问题在这里已经有了答案: How to create an std::function from a move-capturing lambda expression? (3 个回答) 关闭7年前
我有一个源文件,我正在使用它 move 到一个存档目录 关闭。 move (srcfile,dstdir) 但是当存档目标目录中已经存在相同的文件时,它会抛出一个错误,指出无法 move 文件已经存在
这应该有效,但无效并给出以下错误(如下)。 我读过几篇关于 stackoverflow 的帖子 here和 here但在这种情况下似乎没有一个好的答案。我真的希望我只是错过了一些愚蠢的东西,我已经在这
我似乎无法弄清楚为什么会这样。当我运行以下代码时: $uref = APACHE_ROOT . UPLOAD_PATH . $applicant . "_ref_{$email}_{$year}";
我似乎无法弄清楚为什么会这样。当我运行以下代码时: $uref = APACHE_ROOT . UPLOAD_PATH . $applicant . "_ref_{$email}_{$year}";
我的表格行可以上下 move ,但我的问题是数据表行取代了表格标题(第一行)。 我想要一个固定的第一行,这样当您单击向上箭头时,您就不会向上 move 该行来替换标题。 我尝试了一些条件逻辑来检查当前
正如我在Move constructor/operator=中询问的那样,过了一段时间,我同意并接受了这个问题的正确答案,我只是在想,是否有类似“移动析构函数” 这样的东西会在每次移动的对象上调用会有
如果我有一个像这样的 C 类: class C { std::string s; public: C(std::string& s) : s(s) {} C(std::str
我是 C++11 的新手,发现 move 语义和复制省略非常适合编写优雅高效的代码。不过我有一些问题想请教。这里我写了一个模板类 matrix.hpp 并用它来测试 move 语义的行为。 #incl
我在我们的项目中遇到了这样的代码: class A { public: A(A&& obj): valid_(false), data_(obj.data_) {} //... void
move 语义在这个例子中是如何工作的: struct test { int ii[10]; int i; }; test f() { test a; std::cou
假设我有一个类型为 A 的对象 a。 如果我想将其 move 到函数foo(A)。 一个选择是执行 foo(std::move(a)),这将调用 move 构造函数。 但是,假设我正在使用一个我无法控
我用 move 复制构造函数和 move 复制赋值运算符创建了一个简单的应用程序,并且在它们中的每一个上我都做了一个 cout 语句来告诉我,它们正在执行。但是在执行过程中,我没有看到 move 复制
相关问题: Why this move constructor is not called wtih rvalue temporary? [duplicate] Move Constructor vs
我正在努力研究 move 构造函数,并希望通过这个问题获得更多见解。这是一个简单的类。 class A { private: vector Bs; public: /* ..
我是一名优秀的程序员,十分优秀!