在文本文件顶部添加一行

5
我的应用程序从数据中获取信息并将其添加到文本文件中,但我需要编程查看文本文件的第一行是否与以下文本匹配:
DateTime,VirtualIP,VirtualPort,VirtualName,DestinationIP,DestPort,Status,Desired
如果匹配,则继续执行正常功能(下面是片段),如果第一行与上述文本不同,则我想将其插入到第一行而不覆盖当前内容。 我该如何做到这一点?(基本上将所有内容向下推一行,以便我可以在第一行添加所需内容)...顺便说一句,这是保存为可以在Excel中打开的csv文件。
try
{
    // ...
    for (int j = 0; j < memberStatus.Result.Count; j++)
    {
        VirtualMemberStatus status = memberStatus.Result[j];

        //text += String.Format("Name: {4}, Member: {0}:{1}, Status: {2}, Desired: {3}" + Environment.NewLine, status.Member.Address, status.Member.Port, status.EffectiveStatus, status.DesiredStatus, virtualKey.Key);
        text += String.Format("{5},{4},{0},{1},{2},{3}" + Environment.NewLine, status.Member.Address, status.Member.Port, status.EffectiveStatus, status.DesiredStatus, virtualKey.Key.Replace(":", ","), DateTime.UtcNow);
    }
}
catch
{
    //ERROR CODE 2
    //MessageBox.Show("Error occurred, check device name (case senstive) and admin group. This error may also occur due to connection loss, try again.");
    errors += String.Format("{0} Error Code: 2, Error occurred, check device name (case senstive) and admin group. This error may also occur due to connection loss, try again." + Environment.NewLine, DateTime.UtcNow);

}

this.resultsTextBox.Text = text;

这个文件不经常删除,但如果删除了,我希望它在顶部有正确的列名。例如:

DateTime,VirtualIP,VirtualPort,VirtualName,DestinationIP,DestPort,Status,Desired

1
你真的不需要在标题末尾加上 "c#"。标签已经为你做了这个。 - John Saunders
是的,我知道,但我这样做是为了更好的可见性。 - nGX
标签已经为您处理了这个问题。您所做的只是让标题更难读,因此其他人更不可能阅读并帮助您。这不是新闻组或讨论论坛。 - John Saunders
2个回答

8

您需要重写整个文件。

  1. 打开一个新的(临时的!)文件
  2. 写入标题行
  3. 对于每一行输入,写入该行(如果考虑性能问题,请考虑块缓冲)
  4. 刷新并关闭输出文件
  5. 仅当没有错误时,将临时文件移到原位置(通过重命名)。

此过程可以在进程中途发生(IO)错误时防止出现问题。

以下是执行此操作的代码:

using (var input = new StreamReader("input.txt"))
    using (var output = new StreamWriter("input.txt.temp"))
{
    output.WriteLine("headerline"); // replace with your header :)

    var buf = new char[4096];
    int read = 0;
    do 
    {
        read = input.ReadBlock(buf, 0, buf.Length);
        output.Write(buf, 0, read);
    } while (read > 0);

    output.Flush();
    output.Close();
    input.Close();
}

File.Replace("input.txt.temp", "input.txt", "input.txt.backup");

请注意,示例代码甚至创建了备份。一个可能的改进点是明确实例化 FileStream(...., FileMode.CreateNew),以防止覆盖临时文件,如果已经存在该名称的文件。
另一个解决方案是使用System.IO.Path.GetTempFileName()。然而,这样做可能会导致File.Replace不再高效和原子性,因为临时文件夹可能在另一个卷/文件系统上。

这个代码可以运行,但是当我再次运行工具时,它会再次在顶部插入该行。我只想要一次,如何能够寻找第0行,读取它,如果匹配标题则跳过此过程? - nGX
这对我有用,我只是用 if/else 语句来验证第一行是否与我的标题匹配。谢谢! - nGX

0

你需要搜索第一个位置,看它是否匹配这些单词,这段代码片段可以实现你想要的功能。

    Dim filePath As String = "file.txt"
    Dim bufferSize As Integer = 8129

    Dim textToMatch As String = "DateTime,VirtualIP,VirtualPort,VirtualName,DestinationIP,DestPort,Status,Desired"
    Dim textByte As Byte() = ASCIIEncoding.ASCII.GetBytes(text)

    Dim buffer As Byte() = Nothing

    Dim fs As FileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite)
    fs.Read(buffer, 0, bufferSize)


    Dim i As Int32 = fs.Seek(0, SeekOrigin.Begin)
    fs.Position = i

    If fs.Position.Equals(textToMatch) Then

    Else
        fs.Write(textByte, 0, textByte.Length)
    End If

    fs.Flush()
    fs.Close()

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