FileStream 和 StreamWriter - 写入后如何截断文件的其余部分?

FileStream and StreamWriter - How to truncate the remainder of the file after writing?

提问人:Nathan Ridley 提问时间:12/11/2011 最后编辑:Nathan Ridley 更新时间:11/15/2023 访问量:10710

问:

var fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
using(var writer = new StreamWriter(fs))
    writer.Write(....);

如果文件以前包含文本,而新编写的文本比文件中已有的文本短,如何确保文件中过时的尾随内容被截断?

请注意,在这种情况下,不能以截断模式打开文件。当我收到对象时,文件已经打开。上面的代码只是为了说明流的属性。FileStream

编辑

在下面的答案的基础上扩展,解决方案是:

var fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
using(var writer = new StreamWriter(fs))
{
    writer.Write(....);
    writer.Flush();
    fs.SetLength(fs.Position);
}
.NET IO 文件 流编写器

评论

1赞 springy76 7/31/2012
答案/解决方案代码在我看来是错误的:读取 fs。打电话给作家之前的位置。刷新或写入器。Dipose() 不会给你真正的字节数。您很幸运,因为 Stream 在写入时会自动扩展,但由于 2 个长度调整应用于 1 次写入,您的文件可能会变得不必要。

答:

4赞 Russell Troywest 12/11/2011 #1

你可以试试,尽管我不确定效果如何。writer.BaseStream.SetLength(writer.BaseStream.Position)

对于 FileStream,我认为应该将文件截断到当前位置。

18赞 Oded 12/11/2011 #2

使用 SetLength 设置文件的新长度 - 文件应被截断。

请参阅相关问题的答案

评论

0赞 Nathan Ridley 12/11/2011
只是在您发布的同时找到了答案。干杯:)
1赞 Code First 3/16/2017 #3

如果日志文件增长到 1 MB 以上,此代码将截断部分日志文件。

using (FileStream fs = File.Open("C:\\LogFile.txt", FileMode.OpenOrCreate))
{
    int OneMB = 1000000;

    fs.Seek(0, SeekOrigin.Begin);
    if (fs.Length > OneMB)
    { 
        int fileByte = 1;
        fs.Position  = fs.Seek(fs.Length / 2, SeekOrigin.Begin);
        List<byte> bytes = new List<byte>();
        
        while (fileByte > 0)
        {
            fileByte = fs.ReadByte();
            bytes.Add((byte)fileByte);
        }

        fs.SetLength(0);
        fs.Position = 0;
        fs.Write(bytes.ToArray(), 0, bytes.Count());
        
        fs.Seek(0, SeekOrigin.End);
        var stringBytes =  UTF8Encoding.ASCII.GetBytes($"Test1" + Environment.NewLine);
        fs.Write(stringBytes, 0, stringBytes.Length);  
    }
    else
    {
        fs.Seek(0, SeekOrigin.End);
        var stringBytes = UTF8Encoding.ASCII.GetBytes($"Test2" + Environment.NewLine);
        fs.Write(stringBytes, 0, stringBytes.Length); 
    }

    fs.Flush();
}