You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7控制台应用如何用单语句同时输出至控制台与带时间戳文件?

问题描述

我有一个通过Windows任务计划每日执行的.NET 7控制台应用,调试时控制台输出十分有用,但自动执行时该输出不会被保存。我可以通过任务计划将输出重定向到文件,但更希望将内容同时写入控制台和以时间戳命名的文本文件。

如果单独使用文件文本流写入,就需要重复编写每一条Write/WriteLine语句,这是糟糕的设计。因此我想知道,如何仅用一条Write/WriteLine语句,同时将文本写入控制台和文件?

我曾考虑使用ILogger接口,但该应用仅约70行代码,逻辑简洁,且ILogger的日志级别过滤功能对我而言完全冗余,我只需要记录所有内容,因此ILogger对我的项目来说大材小用。

我不希望重定向控制台输出!我想要将控制台流复制到第二个流中。这类似于命令行中的tee命令,但我要的是不依赖任何命令行参数的代码内实现方法。我在Stack Overflow上找到一个旧解决方案,不过仍希望得到适配.NET 7的方案。

适配.NET 7的实现方案

不需要依赖额外框架或.NET 7新特性,通过自定义TextWriter即可实现控制台输出与文件输出的同步,核心思路是让控制台的输出流同时指向原控制台和文件流。

实现步骤

  1. 定义一个继承自TextWriter的类,同时封装原控制台输出流和文件输出流,重写写入方法实现双端输出。
  2. 生成带时间戳的日志文件名,创建文件流。
  3. 将Console.Out和Console.Error替换为自定义的TextWriter,确保所有控制台输出(包括错误信息)都能同步写入文件。

完整代码示例

using System;
using System.IO;

namespace TeeConsoleExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 生成带时间戳的文件名,避免重复
            string logFileName = $"app_log_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
            using var fileStream = new StreamWriter(logFileName, append: false) { AutoFlush = true };
            using var teeWriter = new TeeTextWriter(Console.Out, fileStream);
            using var teeErrorWriter = new TeeTextWriter(Console.Error, fileStream);

            // 替换控制台的标准输出和错误输出
            Console.SetOut(teeWriter);
            Console.SetError(teeErrorWriter);

            // 后续所有Console.WriteLine/Write都会自动同步到控制台和文件
            Console.WriteLine("应用启动时间:" + DateTime.Now);
            Console.WriteLine("执行操作1...");
            try
            {
                // 模拟错误场景
                int num = int.Parse("abc");
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("发生错误:" + ex.Message);
            }
            Console.WriteLine("应用执行完成");
        }
    }

    /// <summary>
    /// 实现类似tee命令的TextWriter,同时写入两个流
    /// </summary>
    public class TeeTextWriter : TextWriter
    {
        private readonly TextWriter _primaryWriter;
        private readonly TextWriter _secondaryWriter;

        public override Encoding Encoding => _primaryWriter.Encoding;

        public TeeTextWriter(TextWriter primary, TextWriter secondary)
        {
            _primaryWriter = primary;
            _secondaryWriter = secondary;
        }

        public override void Write(char value)
        {
            _primaryWriter.Write(value);
            _secondaryWriter.Write(value);
        }

        public override void Write(string value)
        {
            _primaryWriter.Write(value);
            _secondaryWriter.Write(value);
        }

        public override void WriteLine(string value)
        {
            _primaryWriter.WriteLine(value);
            _secondaryWriter.WriteLine(value);
        }

        public override void WriteLine()
        {
            _primaryWriter.WriteLine();
            _secondaryWriter.WriteLine();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _secondaryWriter.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

代码说明

  • TeeTextWriter类:封装了两个TextWriter(原控制台输出和文件流),所有写入操作都会同时转发到这两个流。
  • AutoFlush = true:确保文件流实时写入内容,避免程序意外退出时丢失日志。
  • 替换Console.SetOut和Console.SetError:覆盖系统默认的输出流,后续所有控制台输出都会自动触发双端写入,无需修改原有Console.WriteLine代码。
  • 使用using语句:自动释放文件流和自定义Writer资源,避免内存泄漏。

这个方案完全适配.NET 7,且无需引入任何额外依赖,代码轻量符合你的项目规模需求。


内容的提问来源于stack exchange,提问作者Wim ten Brink

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:20:31