0

現在の環境のデフォルトの Environment.NewLine 文字を変更したいと思います。

コンソールにメッセージを書き込むスタンドアロン アプリケーションが 1 つあります。コア フレームワークがコンソール環境で動作する場合、改行は \r\n です。コア フレームワークを Windows サービスに移動すると、Environment.NewLine が "\n" に変わります。

コンソールの出力をファイルにリダイレクトすると、例のメモ帳から読み取ったときに出力に「windows new lines」がないため、常に「\r\n」を使用するようにコンソールを変更できるようにしたいと考えています。

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);
}

whereは、ファイルが開いたままにならないように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 に答える