gpt4 book ai didi

c# - 如何使用 C# 安全地将数据保存到现有文件?

转载 作者:可可西里 更新时间:2023-11-01 08:10:26 27 4
gpt4 key购买 nike

如何安全地将数据保存到 C# 中已存在的文件中?我有一些序列化到文件中的数据,我很确定直接保存到文件中不是一个好主意,因为如果出现任何问题,文件将被损坏并且以前的版本将丢失。

这就是我到目前为止所做的:

string tempFile = Path.GetTempFileName();

using (Stream tempFileStream = File.Open(tempFile, FileMode.Truncate))
{
SafeXmlSerializer xmlFormatter = new SafeXmlSerializer(typeof(Project));
xmlFormatter.Serialize(tempFileStream, Project);
}

if (File.Exists(fileName)) File.Delete(fileName);
File.Move(tempFile, fileName);
if (File.Exists(tempFile)) File.Delete(tempFile);

问题是当我尝试保存到我的 Dropbox 中的文件时,有时我会遇到异常,告诉我它无法保存到已经存在的文件中。显然,第一个 File.Delete(fileName); 没有立即删除文件,而是稍等片刻。所以我在 File.Move(tempFile, fileName); 中遇到异常,因为该文件存在,然后文件被删除,我的文件丢失了。

我在我的 Dropbox 中使用了其他应用程序来处理文件,它们以某种方式设法不弄乱它。当我尝试保存到我的 Dropbox 文件夹中的文件时,有时我会收到一条消息,告诉我该文件正在被使用或类似的东西,但我从来没有遇到过文件被删除的问题。

那么这里的标准/最佳实践是什么?

好的,这就是我在阅读所有答案后得出的结论:

private string GetTempFileName(string dir)
{
string name = null;
int attempts = 0;
do
{
name = "temp_" + Player.Math.RandomDigits(10) + ".hsp";
attempts++;
if (attempts > 10) throw new Exception("Could not create temporary file.");
}
while (File.Exists(Path.Combine(dir, name)));

return name;
}

private void SaveProject(string fileName)
{
bool originalRenamed = false;
string tempNewFile = null;
string oldFileTempName = null;

try
{
tempNewFile = GetTempFileName(Path.GetDirectoryName(fileName));

using (Stream tempNewFileStream = File.Open(tempNewFile, FileMode.CreateNew))
{
SafeXmlSerializer xmlFormatter = new SafeXmlSerializer(typeof(Project));
xmlFormatter.Serialize(tempNewFileStream, Project);
}

if (File.Exists(fileName))
{
oldFileTempName = GetTempFileName(Path.GetDirectoryName(fileName));
File.Move(fileName, oldFileTempName);
originalRenamed = true;
}

File.Move(tempNewFile, fileName);
originalRenamed = false;

CurrentProjectPath = fileName;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if(tempNewFile != null) File.Delete(tempNewFile);

if (originalRenamed) MessageBox.Show("'" + fileName + "'" +
" have been corrupted or deleted in this operation.\n" +
"A backup copy have been created at '" + oldFileTempName + "'");
else if (oldFileTempName != null) File.Delete(oldFileTempName);
}
}

Player.Math.RandomDigits 只是我创建的一个小函数,它创建一个包含 n 个随机数字的字符串。

除非操作系统出现问题,否则我不明白这怎么会弄乱原始文件。这与 Hans 的回答非常接近,除了我首先将文件保存到一个临时文件中,这样,如果在序列化时出现问题,我不需要将文件重命名回它的原始名称,这也可能出错。请!如果您发现任何缺陷,请告诉我。

最佳答案

我不确定这有多安全,但假设您的操作系统没有崩溃,您猜怎么着?有一个应用程序:File.Replace

File.Replace(tempFile, fileName, backupFileName);

我认为你在危急情况下真正需要的是transactions ;只有这样,您才能保证不会丢失数据。看看this article对于 .NET 解决方案,但请注意,它可能比简单的文件替换解决方案更难使用。

关于c# - 如何使用 C# 安全地将数据保存到现有文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5386795/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com