【问题标题】:.NET Environment.NewLine - how to setup programmatically.NET Environment.NewLine - 如何以编程方式设置
【发布时间】:2012-07-27 09:11:00
【问题描述】:

我想更改当前环境的默认 Environment.NewLine 字符。

我有一个将消息写入控制台的独立应用程序。当核心框架在控制台环境中工作时,新行是 \r\n。当我将核心框架移动到 Windows 服务中时,Environment.NewLine 更改为“\n”。

我希望能够将控制台更改为始终使用“\r\n”,因为当我将控制台的输出重定向到文件时,从示例记事本读取时输出没有“windows 换行符”。

我希望 Console.WriteLine 可以随时使用 \r\n。

编辑:

我正在重定向 Console.out:

        ConsoleOut = File.AppendText(fileName);
        ConsoleOut.AutoFlush = true;


        Console.SetOut(ConsoleOut);
        Console.SetError(ConsoleOut);

每个 Console.WriteLine 或 Console.Write 都会发送到一个文件,但正如我所说,我在 Windows 服务和独立 Windows 环境中遇到不同的行为。

【问题讨论】:

  • 这两个陈述是矛盾的:“当核心框架在控制台环境中工作时,新行是\r\n”,和“我希望Console.WriteLine 可以在任何时候使用\r\n想要”。
  • Environment.NewLine 是一个常数。 dotnetperls.com/newline
  • 为什么如果我从 Windows 服务运行相同的库,Console.WriteLine 会输出我 \n 而不是 \r\n。我将 Console.out 重定向到一个文件。相同的代码在两个不同的环境中运行。
  • 我刚刚从我的一项服务中检查了我的日志;它绝对是 CRLF,即字节 13、10。我认为您需要 a:仔细检查您的文件,b:检查您以后没有更改它们(例如,在通过 FTP 传输期间),以及 c:提供一个示例实际上显示它生成 CR 或 LF 但不生成 CRLF
  • 我会深入检查它们。谢谢。您在代码示例方面给了我很大的帮助,但我仍然不知道问题出在哪里,所以我会等待分配答案,直到找到解决方案。

标签: c# .net newline environment


【解决方案1】:

我不相信这一点:

当我将核心框架移动到 Windows 服务中时,Environment.NewLine 更改为“\n”

我检查了get_NewLine() 的 IL,它被硬编码为:

ldstr "\r\n"
ret

基本上是这样;问题不是你想的那样;更改 Environment.NewLine 不会做任何事情(并且:不可能)。

那么:你是如何重定向的?我倾向于这样做:

if (!Environment.UserInteractive)
{
    var tw = new SlowWriter(Path.Combine(logPath,"{0}.log"));
    Console.SetError(tw);
    Console.SetOut(tw);
}

其中SlowWriter 是一个自定义类型(子类TextWriter),可确保文件不会保持打开状态;较慢,但相当健壮:

class SlowWriter : TextWriter
{ // this opens and closs each time; slower, but doesn't lock the file
    private readonly string path;
    public SlowWriter(string path)
    {
        this.path = path;
    }
    public override System.Text.Encoding Encoding
    {
        get { return System.Text.Encoding.UTF8; }
    }
    private TextWriter Append()
    {
        var finalPath = string.Format(path, DateTime.UtcNow.ToString("yyyyMMdd"));
        return File.AppendText(finalPath);
    }
    public override void Write(string value)
    {
        lock (this)
        {
            using (var file = Append())
            {
                file.Write(value);
            }
        }
    }
    public override void Write(char[] buffer, int index, int count)
    {
        lock(this)
        {
            using (var file = Append())
            {
                file.Write(buffer, index, count);
            }
        }
    }
    public override void Write(char[] buffer)
    {
        lock (this)
        {
            using (var file = Append())
            {
                file.Write(buffer);
            }
        }
    }
}

【讨论】:

  • 谢谢马克。我正在重定向 Console.out
【解决方案2】:

你不能修改 System.Environment.NewLine

MSDN Reference

这是一个只读属性

public static string NewLine { get; }

Here 你可以读到 NewLine 总是返回“\r\n”。

接下来我们研究 get_NewLine,它是用这个 IL 实现的。你 可以看到它只是简单地返回了“\r\n”字符串字面量。

所以我认为您可以在应用程序中使用常量,例如

public const NEWLINE = "\r\n"; 

只需使用它来代替 Environment.NewLine。

Console.WriteLine 不要在内部使用 Environment.NewLine 而是使用回车后跟换行符。参考Here

默认的行终止符是一个字符串,其值为一个回车符 return 后跟换行符(C# 中的 "\r\n" 或 Visual 中的 vbCrLf 基本的)。您可以通过设置 TextWriter.NewLine 属性的 Out 属性为另一个字符串。这 示例提供了说明。

还有一个关于如何修改此属性的示例:

 // Redefine the newline characters to double space.
 Console.Out.NewLine = "\r\n\r\n";

【讨论】:

  • 我同意 System.Environment.NewLine 不能被修改。我认为 Console.WriteLine 正在使用 System.Environment.NewLine
  • 使用有关 Console.Writeline 的新信息编辑了答案
  • 如果这个 Console.Out.NewLine = "\r\n\r\n";有效,那么这就是我正在寻找的答案。
【解决方案3】:

那么我认为你不应该使用Environment.NewLine。您所看到的正是拥有它的确切原因。我认为你最好定义一个你使用的appSettings,并将它设置为你的控制台应用程序和 Windows 服务应用程序的不同值。

更新: 另请参阅 Marc Gravell 的回答。即使它是硬编码的,我也不会尝试用上述动机来改变它。

【讨论】:

  • 我没有使用它。我只认为 Console.WriteLine 正在使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-13
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多