Environment.NewLine和TextWriter.NewLine属性的用途是什么

Mis*_*hax 0 c# io newline

我有一种奇怪的情况,我不了解与'\n'我要发送到文件的换行符有关的情况。新行似乎并没有给根据被处理NewLine的性质TextWriterEnvironment。此代码演示:

String baseDir = Environment.GetEnvironmentVariable("USERPROFILE") + '\\';
String fileName = baseDir + "deleteme5.txt";
FileInfo fi = new FileInfo(fileName);
fi.Delete();
FileStream fw = new FileStream(fileName, FileMode.CreateNew, FileAccess.Write);
StreamWriter sw = new StreamWriter(fw);
Console.WriteLine(Environment.NewLine.Length);
Console.WriteLine(sw.NewLine.Length);
sw.Write("1\uf0f1\n2\ue0e1\n3\ud0d1\n");
sw.Flush();
sw.Close();
Run Code Online (Sandbox Code Playgroud)

当我运行此控制台输出是

2
2

以十六进制模式查看文件时,我得到:

00000000h:31 EF 83 B1 0A 32 EE 83 A1 0A 33 ED 83 91 0A; 1.2.3íƒ'。

显然,API包含两个字符,当您查看文件时,只有一个字符。现在,当我查看TextWriter中Write方法的描述时,它表明Write方法不会用NewLine属性代替0A。好吧,如果Write方法没有考虑到这一点,那么拥有一个而不是两个NewLine属性有什么用?这些是做什么用的?

Han*_*ant 5

程序员有很长的历史,他们同意在将文本写入文件时应如何编码文本。ASCII和Unicode在一定程度上帮助了Babel塔的升级。但是,从未有什么字符表示行尾。

  • Windows使用回车+换行控制代码。 "\r\n"在C#代码中。
  • Unix风格仅使用'\n'C#代码中的单个换行控制代码。
  • Apple历史上只使用'\r'C#代码中的单个回车控制代码。

.NET需要与所有这些不兼容的选择兼容。因此,它添加了Environment.NewLine属性,它具有操作系统的默认行结束顺序。请注意如何使用Mono或Silverlight在Unix和Apple计算机上运行.NET代码。

由于TextWriter抽象类编写文本文件,因此需要知道使用什么顺序。因此它具有NewLine属性,其默认值与Environment.NewLine相同。您几乎总是使用该文件,但是如果您需要创建一个文本文件,该文件可以被另一个操作系统上的程序读取,则可能需要更改它。

您在程序中犯的错误是您对行终止符进行了硬编码。您在字符串中使用了“ \ n”。这将完全绕过.NET属性,您将永远只在文本文件中看到单行换行控制代码。0x0A是换行符。您的控制台输出将显示“ 2”,因为它仅显示NewLine属性的字符串长度。在Windows上,“ \ r \ n”为2。

使用.NET属性的最简单方法是使用WriteLine()而不是Write():

  sw.WriteLine("1\uf0f1");
  sw.WriteLine("2\ue0e1");
  sw.WriteLine("3\ud0d1"); 
Run Code Online (Sandbox Code Playgroud)

这也使您的代码可读性很好,运行时也不会变慢。如果要保留一线,则可以使用复合格式:

  sw.Write("1\uf0f1{0}2\ue0e1{0}3\ud0d1{0}", Environment.NewLine);
Run Code Online (Sandbox Code Playgroud)