c# - C# Windows 窗体无法将数据重写到文件
问题描述
我有一个应该将数据保存到文件的 Windows 窗体应用程序。为此,我称之为:
public void SaveVocabulary()
{
string line;
try
{
//create backup of file
File.Copy(ConfigData.Filename, ConfigData.Filename.Replace(".txt", "_backup.txt"), true);
// delete all content
File.Create(ConfigData.Filename).Close();
foreach (VocabularyData vocable in vocList)
{
line = vocable.VocGerman.Replace('|', '/') + "|";
line += vocable.VocEnglish.Replace('|', '/') + "|";
File.AppendAllText(ConfigData.Filename, line + Environment.NewLine);
}
// delete backup
File.Delete(ConfigData.Filename.Replace(".txt", "_backup.txt"));
}
catch (Exception ex)
{
throw new Exception("Error saving Vocabulary: " + ex.Message, ex);
}
}
但是每次我第二次通过该行时File.Create(ConfigData.Filename).Close();
,代码都会抛出一个异常告诉我,我无法访问该文件,因为它被另一个进程使用。
Der Prozess kann nicht auf die Datei "C:\Users\some-path\Vocabulary.txt" zugreifen, da sie von einem anderen Prozess verwendet wird。
根据文档,该文件由File.AppendAllText
. 我也尝试过StreamWriter
明确地关闭它。这也引发了同样的异常。此外,没有其他人在使用该文件。(如果您知道在我的程序运行时阻止某人打开文件进行写入的方法,请告诉我该怎么做。)
请告诉我为什么会出现这种情况?保存后如何确保文件“免费”?所以我可以稍后再保存它。
编辑:这是我加载文件的方式:
public List<VocabularyData> LoadVocabulary()
{
try
{
vocList = new List<VocabularyData>();
string[] lines = File.ReadAllLines(GetFileName());
string[] voc;
VocabularyData vocable;
foreach (string line in lines)
{
voc = line.Split('|');
vocable = new VocabularyData();
vocable.VocGerman = voc[0];
vocable.VocEnglish = voc[1];
vocable.CreationDate = DateTime.Parse(voc[2]);
vocable.AssignedDate = DateTime.Parse(voc[3]);
vocable.SuccessQueue = voc[4];
vocable.TimeQueue = voc[5];
vocList.Add(vocable);
}
}
catch (Exception ex)
{
throw new Exception("Error loading Vocabulary: " + ex.Message, ex);
}
return vocList;
}
解决方案
让我们摆脱显式Stream
s ( File.Create(ConfigData.Filename).Close();
) 并.Net
为您完成工作:
using System.Linq;
...
// backup - same directory as ConfigData.Filename
// same filename as ConfigData.Filename with _backup.txt suffix
string backUpName = Path.Combine(
Path.GetDirectoryName(ConfigData.Filename),
Path.GetFileNameWithoutExtension(ConfigData.Filename) + "_backup.txt");
File.Copy(ConfigData.Filename, backUpName, true);
// lines we want to save (see comments below)
var lines = vocList
.Select(vocable => string.Join("|", // do not hardcode, but Join into line
vocable.VocGerman.Replace('|','/'),
vocable.VocEnglish.Replace('|', '/'),
vocable.CreationDate.ToString("dd.MM.yyyy"),
vocable.AssignedDate.ToString("dd.MM.yyyy"),
vocable.SuccessQueue,
vocable.TimeQueue,
""
));
File.WriteAllLines(ConfigData.Filename, lines);
File.Delete(backUpName);
编辑:文件读取例程可以简化为
public List<VocabularyData> LoadVocabulary() {
try {
return File
.ReadLines(GetFileName())
.Where(line => !string.IsNullOrWhiteSpace(line)) // to be on the safe side
.Select(line => line.Split('|'))
.Select(voc => new VocabularyData() {
VocGerman = voc[0],
VocEnglish = voc[1],
CreationDate = DateTime.Parse(voc[2]),
AssignedDate = DateTime.Parse(voc[3]),
SuccessQueue = voc[4],
TimeQueue = voc[5]
})
.ToList();
}
catch (IOException ex) {
//TODO: do not throw general Exception but derived
throw new InvalidOperationException($"Error loading Vocabulary: {ex.Message}", ex);
}
}
推荐阅读
- sql-server - 从定义的数据透视表创建索引视图
- php - docker 和 couchbase sdk 安装
- javascript - Javascript 运行时的哪一部分负责将回调放入回调队列?
- python - 无法打开文件'demo.py':[Errno 2] 通过 bash 脚本运行时没有这样的文件或目录
- php - 如何将多维数组存储到简单数组
- sql - 在继承层次结构中声明一个表,其中子级还引用基表中的另一个条目
- php - Laravel 刀片问题
- android - 颤振显示旧错误
- html - 在 flex 容器中将搜索字段居中,同时将徽标保持在右侧?
- c# - C#,NetCore 3.0 - 方法:[HttpGet]