如何在文件已存在时覆盖文件?

29

我正在制作一个音乐播放器。它有两个窗体;一个是主要区域,用于播放音乐。第二个窗体有一个CheckedListBox,您可以在其中选择所需的mp3。 当我点击按钮时,它会将选择保存在.txt文件中,以便我可以在第一个窗体中访问它们,我将把字符串放入音乐播放器路径中以查找文件。

这是我的第二个窗口中的代码,我用它将所选歌曲保存到.txt文件中。

private void selectbtn_Click(object sender, EventArgs e)
{
    if (File.Exists(@"C:\Users\Me\Desktop\JAM_MACHINE\JAMS\record.txt"))
    {
       File.WriteAllText(@"C:\Users\Me\Desktop\JAM_MACHINE\JAMS\record.txt", String.Empty);
    }

    string[] checkedtitles = new string[checkedListBox1.CheckedItems.Count]; 

    for (int ii = 0; ii < checkedListBox1.CheckedItems.Count; ii++)
    {
        checkedtitles[ii] = checkedListBox1.CheckedItems[ii].ToString();
    }
    string selectedSongs = String.Join(Environment.NewLine, checkedtitles); 

    songRecord.writeRecord(selectedSongs); //I initialised the class containing streamwriter/reader, and called it songRecord
    this.Close();   
}
无论何时我关闭程序并再次打开它,都无法重写/清除.txt文件。 它只会添加到现有文件中。 我做错了什么吗?
这是我的streamreader/writer代码。 我很确定在运行后也关闭了它,但也许有人可以找出问题所在:
namespace songss
{
    class DataRecord
    {
    public void writeRecord(string line)
    {
        StreamWriter sw = null;
        try
        {
            sw = new StreamWriter(@"C:\Users\Me\Desktop\JAM_MACHINE\record.txt", true);
            sw.WriteLine(line);
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("Error: File not found.");
        }
        catch (IOException)
        {
            Console.WriteLine("Error: IO");
        }
        catch(Exception)
        {
            throw;
        }
        finally
        {
            if (sw != null)
                sw.Close();
        }
        }

 public void readRecord()
    {
        StreamReader sr = null;
        string myInputline;
        try
        {
            sr = new StreamReader(@"C:\Users\Me\Desktop\JAM_MACHINE\record.txt");
            while ((myInputline = sr.ReadLine()) != null) ; //readline reads whole line
            Console.WriteLine(myInputline);
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("Error: File not found");
        }
        catch(IOException)
        {
            Console.WriteLine("Error: IO");
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            if (sr != null)
                sr.Close();
        }
    }
    }
    }

3
如果该文件存在,为什么不直接删除它? - JohanP
3
你的 songRecord.writeRecord 做了什么?如果在清除文件之前打开它,它可能已经读入了当前的文本。 - Rob
根据API文档,File.WriteAllText应该替换内容。如果没有替换,请提交错误报告。 - Hubert Grzeskowiak
2
这是清空文件的代码。请粘贴将列表写入文件的代码。那一部分存在错误。我很确定你可能没有关闭流编写器或文件。这就是为什么文件被锁定,第二次尝试写入时,之前的锁定状态没有清除并引起问题的原因。 - brainless coder
只是一个小问题:为什么不将您的选择保存在静态属性中?这样您就不需要文件,问题也会自行解决。 - Romano Zumbé
显示剩余2条评论
3个回答

56

WriteAllText

File.WriteAllText方法应该满足您的需求。

创建一个新文件,将指定字符串写入文件,然后关闭文件。如果目标文件已经存在,则会被覆盖。

StreamWriter

StreamWriter类也有覆盖/追加选项:

通过使用默认编码和缓冲区大小为指定文件初始化StreamWriter类的新实例。如果文件存在,则可以覆盖或追加到该文件中。

public StreamWriter(
    string path,
    bool append
)

例子:

using (StreamWriter writer = new StreamWriter("test.txt", false)){ 
    writer.Write(textToAdd);
}

看你的代码,你传入了true,这意味着追加。

sw = new StreamWriter(@"C:\Users\Me\Desktop\JAM_MACHINE\record.txt", true);
sw.WriteLine(line);

.NET Compact Framework

如果您陷入了不支持任何内容(例如紧凑框架)的.NET版本中,您也可以自己实现WriteAllText

static void WriteAllText(string path, string txt) {
    var bytes = Encoding.UTF8.GetBytes(txt);
    using (var f = File.Open(path, FileMode.Create)) {
        f.Write(bytes, 0, bytes.Length);
    }
}

在C# .NET Compact Framework中,没有File.WriteAllText。有什么替代方案吗?谢谢。 - Rui Miguel Pinheiro
1
@RuiMiguelPinheiro 我添加了一些代码,你可能可以使用。 - Nic
1
OpenWrite是危险的,如果你写入的字节数比文件中已有的少,那么文件将包含新旧数据的混合。我建议使用File.Open和FileMode.Create代替。 - Hogan
1
@Hogan 感谢反馈,我已经更新了示例。 - Nic

4

使用此功能

File.WriteAllText(@"C:\Users\Me\Desktop\JAM_MACHINE\JAMS\record.txt", line);

代替
sw = new StreamWriter(@"C:\Users\Me\Desktop\JAM_MACHINE\record.txt", true);
sw.WriteLine(line);

-3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接