【问题标题】:How to truncate a file in c#?如何在c#中截断文件?
【发布时间】:2011-09-26 03:30:30
【问题描述】:

我正在使用 Trace.Writeln() 函数将 C# 程序完成的操作写入文件。但是文件变得太大了。当它增长到 1MB 时如何截断这个文件?

TextWriterTraceListener traceListener = new TextWriterTraceListener(File.AppendText("audit.txt"));
Trace.Listeners.Add(traceListener);
Trace.AutoFlush = true;

上面的块应该添加什么

【问题讨论】:

  • 您应该指定要保留的日志部分。

标签: c# .net file truncate


【解决方案1】:

相对于自己尝试做这件事,我真的推荐使用类似 log4net 的东西;它内置了很多这种有用的功能。

【讨论】:

  • 由于您实际上并没有回答这个问题,所以这应该是一个评论。
  • @Gabe:我不认为这是一个不恰当的答案,即回答 OP 规定的方法显示出一些低效率的问题,并建议一种替代方法。
  • 好的答案显示代码或链接到要使用的特定功能。如果您希望这是一个好的答案,请展示如何使用 log4net 来完成 OP 的要求。
【解决方案2】:

试试FileStream.SetLength

FileStream fileStream = new FileStream(...);
fileStream.SetLength(sizeInBytesNotChars);

【讨论】:

  • +1 如果 OP 使用FileStream,这是最简单的解决方案,使用SetLength(0)
  • 终止进程后,如果我重新创建一个新进程,那么上面的代码会将文本附加到现有文件中吗?
  • 如果您在活动的FileStream 上执行SetLength(0),则会截断基础文件。
  • 我们注意到具有非零长度的 FileStream.SetLength 对于日志文件来说是一个非常糟糕的主意;但是我发现这个问题有一个更合理的案例,这是正确的解决方案。
【解决方案3】:

通过这样做:

if(new FileInfo("<your file path>").Length > 1000000)
{
    File.WriteAllText("<your file path>", "");
}

【讨论】:

  • 我建议看一下1000000的值...记住,1 kbyte = 1024 bytes,同样适用于mb
  • 就我个人而言,我不会以这种方式检查文件长度,这将需要大量的new FileInfo 调用(每次写入一个)。 OP 用来写入文件的类很可能有一些方法来跟踪大小,如果它是 FileStream,例如使用 Position 属性。
  • @Oscar:我知道,只是给出主旨,需要改编。
  • 这不能做滚动日志。
【解决方案4】:

关闭文件,然后使用FileMode.Truncate 重新打开它。

一些日志实现在重新打开之前以旧名称将旧文件存档,以保留更大的数据集,而不会让任何文件变得太大。

【讨论】:

  • 这会将文件截断为 0 字节,即你扔掉整个文件。这可能是 OP 想要做的……或者他们可能想要保留一些,在这种情况下不要这样做。
【解决方案5】:

当文件超过 500000 字节时,它将从文件中删除开始的 250000 字节,因此剩余的文件长度为 250000 字节。

FileStream fs = new FileStream(strFileName, FileMode.OpenOrCreate);
        if (fs.Length > 500000)
        {
            // Set the length to 250Kb
            Byte[] bytes = new byte[fs.Length];
            fs.Read(bytes, 0, (int)fs.Length);
            fs.Close();
            FileStream fs2 = new FileStream(strFileName, FileMode.Create);
            fs2.Write(bytes, (int)bytes.Length - 250000, 250000);
            fs2.Flush();
        } // end if (fs.Length > 500000) 

【讨论】:

  • 这会将整个文件读入内存。如果它真的很大,那就不理想了。
【解决方案6】:

也许这是一个简单的解决方案:

// Test the file is more or equal to a 1MB ((1 * 1024) * 1024)
// There are 1024B in 1KB, 1024KB in 1MB
if (new FileInfo(file).length >= ((1 * 1024) * 1024))
{
    // This will open your file. Once opened, it will write all data to 0
    using (FileStream fileStream = new FileStream(file, FileMode.Truncate, FileAccess.Write))
    {
        // Write to your file.
    }
}

【讨论】:

    【解决方案7】:

    如果您不想保留内容,或者将它们移动到跟踪周期更新的辅助文件中(无论是按天还是其他周期长度),我建议您只使用以下简单方法重写文件:

        private void Truncate(readFile)     // to clear contents of file and note last time it was cleared
        {
            string readFile = readPath + ".txt";
            string str = string.Format("{0} : Truncated Contents", DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt"));
            using (StreamWriter truncate = new StreamWriter(readFile))
            {
                truncate.WriteLine(str); // truncates and leaves the message with DateTime stamp
            }
        }
    

    另一方面,如果您想将内容保存到文件中以截断它们的日期,您可以结合上述方法使用以下方法:

        private void Truncate(readPath)     // to clear contents of file, copy, and note last time it was cleared and copied
        {
            if (!File.Exists(readPath))    // create the new file for storing old entries
            {
                string readFile = readPath + ".txt";
                string writeFile = readPath + DateTime.Now.ToString("_dd-MM-yyyy_hh-mm") + ".txt"; // you can add all the way down to milliseconds if your system runs fast enough
                using (FileStream fs = new FileStream(writeFile, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    using (StreamWriter write = new StreamWriter(fs))
                    using (StreamReader file = new StreamReader(readFile))
                    {
                        write.WriteLine(string.Format(textA, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt")));
                        string line;
                        var sb = new StringBuilder();
                        while ((line = file.ReadLine()) != null)
                        {
                            line = line.Replace("\0", ""); // removes nonsense bits from stream
                            sb.AppendLine(line);
                        }
                        write.WriteLine(sb.ToString());
                        string textB = "{0} : Copied Source";
                        write.WriteLine(string.Format(textB, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt")));
                    }
                }
                string str = string.Format("{0} : Truncated Contents", DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt"));
                using (StreamWriter truncate = new StreamWriter(readFile))
                {
                    truncate.WriteLine(str); // truncates and leaves the message with DateTime stamp
                }
            }
        }
    

    无论哪种方式,您都可以将您选择的方法与以下块一起使用:

    if(new FileInfo("audit.txt").Length >= 0xfffff) // hex for 1MB
    {
        Truncate("audit");
    }
    

    我希望这对未来的读者有所帮助。

    谢谢,

    【讨论】:

      【解决方案8】:

      迟到的答案,但你可以试试:

      StreamWriter sw = new StreamWriter(YourFileName, false);
      sw.Write("");
      sw.Flush();
      sw.Close();
      

      发送false 作为StreamWriter() 的第二个参数告诉它不要追加,导致它覆盖文件。在这种情况下,使用空字符串,有效地截断它。

      【讨论】:

        猜你喜欢
        • 2010-10-26
        • 2011-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-14
        • 2012-09-08
        • 1970-01-01
        相关资源
        最近更新 更多