0

我想更改当前环境的默认 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 环境中遇到不同的行为。

4

3 回答 3

4

我不相信这一点:

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

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

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);
            }
        }
    }
}
于 2012-07-27T09:16:18.793 回答
2

您不能修改 System.Environment.NewLine

MSDN 参考

这是一个只读属性

public static string NewLine { get; }

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

接下来我们研究 get_NewLine,它是用这个 IL 实现的。您可以看到它只是返回“\r\n”字符串文字。

所以我认为你可以在你的应用程序中使用一个常量,比如

public const NEWLINE = "\r\n"; 

并且只需使用它而不是 Environment.NewLine。

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

默认行终止符是一个字符串,其值是一个回车后跟一个换行符(在 C# 中为“\r\n”,在 Visual Basic 中为 vbCrLf)。您可以通过将 Out 属性的 TextWriter.NewLine 属性设置为另一个字符串来更改行终止符。该示例提供了一个说明。

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

 // Redefine the newline characters to double space.
 Console.Out.NewLine = "\r\n\r\n";
于 2012-07-27T09:17:42.843 回答
1

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

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

于 2012-07-27T09:16:26.227 回答