C#Windows窗体无法将数据重写到文件中

时间:2019-08-01 08:45:29

标签: c# windows forms system.io.file

我有一个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);
    }
}

但是每隔2次我通过行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;
}

2 个答案:

答案 0 :(得分:3)

让我们摆脱明确的StreamFile.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);
  }
}

答案 1 :(得分:0)

OMG

我发现了我的错误!

我将该文件用作邮件的附件。当我再次保存邮件时,我猜邮件尚未发送。

感谢所有帮助。 我终于用Process Explorer和Exploring在文件被锁定的时候发现了。