如果保存到 .csv 文件时文件已经存在,则防止应用程序崩溃

Prevent app from crashing if the file is already when saving to a .csv

我目前有以下代码可以将一些数据保存到 .csv 文件中。一切正常,但我遇到的一个问题是,如果 .csv 文件打开,并且您尝试保存一组新数据,应用程序会崩溃。我认为将其设置为只读可以防止出现此问题,但我不确定该怎么做。例如。如果最后一个文件保存在 C:\Users\Documents\data.csv,并且用户打开了那个 data.csv 文件。然后用户使用相同的路径保存另一组数据,然后应用程序崩溃。

SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.FileName = tbSave.Text;
saveFileDialog.Filter = ".csv|*.csv";
if(saveFileDialog.ShowDialog() == DialogResult.OK)
{
    File.WriteAllText(saveFileDialog.FileName, sb.ToString());
    MessageBox.Show("Save Complete!" + "\n" + "Number of skips recorded: " + skips.ToString() + "\n" + "Elasped time recorded (ms): " + time.ToString());
}

您无法将数据写入由 Excel 打开的文件。这就是问题的核心问题。

解决方法:写入前必须关闭文件。

为此,您必须处理用户打开文件的情况。

if(saveFileDialog.ShowDialog() == DialogResult.OK)
{
    try{
        File.WriteAllText(saveFileDialog.FileName, sb.ToString());
    }
    catch(Exception ex)
    {
        //file is being opened.
    }
}

catch 部分,您可以选择 3 个选项: 1. 您要求用户关闭文件然后返回您的应用程序。

catch(Exception ex)
{
     //file is being opened.
     MessageBox.Show("close file xxx please, then redo your work");
}

2。一个更优雅的解决方案是提醒用户我们将关闭 Excel。我们喜欢吗?是的,我们终止所有进程 Excel 并继续执行您的代码。

    catch(Exception ex)
    {
         //file is being opened.
         MessageBox.ShowDialog("Kill all Excel?") == No
         return;

         Process myProcess = new Process();
         myProcess.EnableRaisingEvents = true;
         myProcess.Exited += new EventHandler(myProcess_Exited);
         myProcess.Start("CMD.exe","taskkill /f /im excel.exe");         
    }

private void myProcess_Exited(object sender, System.EventArgs e)
    {

        eventHandled = true;
        File.WriteAllText(saveFileDialog.FileName, sb.ToString());
    }
  1. 一个更困难的解决方案是只删除文件的一个实例 Excel。但它会产生异常,因为我们无法正确处理 Excel
  2. 的行为

与第二个解决方案相似,但

myProcess.Start("CMD.exe","taskkill /FI "WindowTitle eq Microsoft Excel - filename.xls");

我将保存的文件设为只读。这样可以确保它不会被覆盖,并且如果 excel 文件打开,应用程序也不会崩溃。在我的目的范围内,这个解决方案工作正常。

SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.FileName = tbSave.Text;
saveFileDialog.Filter = ".csv|*.csv";
if(saveFileDialog.ShowDialog() == DialogResult.OK)
{    
    File.WriteAllText(saveFileDialog.FileName, sb.ToString());
    File.SetAttributes(saveFileDialog.FileName, FileAttributes.ReadOnly);
    MessageBox.Show("Save Complete!" + "\n" + "Number of skips recorded: " + skips.ToString() + "\n" + "Elasped time recorded (ms): " + time.ToString());
}