我有一个奇怪的情况,我不理解与我发送到文件的换行符'\n'
有关。根据{{1}}和NewLine
的{{1}}属性,似乎不会对换行符进行处理。此代码演示了:
TextWriter
当我运行它时,控制台输出是
2
2
当我以十六进制模式查看我的文件时,我得到:
<00> 00000000h:31 EF 83 B1 0A 32 EE 83 A1 0A 33 ED 83 91 0A; 1.2.3탓。
显然,API会显示两个字符,当您查看文件时,只有一个字符。现在,当我查看TextWriter中Write方法的描述时,它表明Write方法不会将0A替换为NewLine属性。好吧,如果Write方法没有考虑到这一点,那么只有两个NewLine属性的用途是什么?这些东西是为了什么?
答案 0 :(得分:4)
程序员有很长的历史不同意在将文本写入文件时应如何编码文本。 ASCII和Unicode在一定程度上帮助了巴别塔的水平。但是什么字符表示一行的结尾从未达成一致。
"\r\n"
。'\n'
。'\r'
。.NET需要兼容所有这些不兼容的选择。因此它添加了Environment.NewLine属性,它具有操作系统的默认行结束顺序。请注意如何在具有Mono或Silverlight的Unix和Apple机器上运行.NET代码。
抽象TextWriter类需要知道在写入文本文件时要使用的序列。所以它有一个NewLine属性,它的默认值与Environment.NewLine相同。您几乎总是使用它,但如果您需要创建一个由另一个操作系统上的程序读取的文本文件,您可能想要更改它。
您在程序中犯的错误是硬编码行终止符。你在字符串中使用了'\ n'。这完全绕过了.NET属性,您只能在文本文件中看到单行换行控制代码。 0x0A是换行符。您的控制台输出显示“2”,因为它只显示NewLine属性的字符串长度。对于“\ r \ n”,Windows上为2。
使用.NET属性的最简单方法是使用WriteLine()而不是Write():
sw.WriteLine("1\uf0f1");
sw.WriteLine("2\ue0e1");
sw.WriteLine("3\ud0d1");
这使得您的代码也可以很好地读取,它在运行时并不慢。如果你想保留单行,那么你可以使用复合格式:
sw.Write("1\uf0f1{0}2\ue0e1{0}3\ud0d1{0}", Environment.NewLine);
答案 1 :(得分:1)
如果选择通过将\ n发送给streamwriter来生成'linebreaks',那么框架就无法干扰它。如果您希望框架遵守NewLine属性,请使用writer的WriteLine方法并设置Writer的NewLine属性。
像这样调整你的代码:
sw.NewLine = Environment.NewLine; // StreamWriter uses \r\n by default
sw.WriteLine("1\uf0f1")
sw.WriteLine("2\ue0e1");
sw.WriteLine("3\ud0d1");
或者有一个自定义StreamWriter覆盖Write方法:
public class MyStreamWriter:StreamWriter
{
public MyStreamWriter(Stream s):base(s)
{
}
public override void Write(string s)
{
base.Write(s.Replace("\n",Environment.NewLine));
}
}
或者,如果您只想要处理一行:
sw.Write("1\uf0f1\n2\ue0e1\n3\ud0d1\n".Replace("\n", Environment.NewLine));
答案 2 :(得分:0)
如果隐式使用,如在调用WriteLine方法中或在Write(String.Concat(“Hello”,Environment.NewLine)中显式使用,则会获得为您的环境定义的行尾字符。如果您不要使用它并使用说'\ n'或甚至'$',然后你说无论我在什么环境,行将像我说的那样结束。如果你想比较行为,写一点代码并在windows和linux(mono)下运行它
答案 3 :(得分:0)
所有换行符都是字符串中的\ n转换为单字符ASCII换行符(0x0A)(不是Windows换行符0D0A)并输出到写入器中的流为0x0A,除非程序员采取一些明确的步骤将字符串中的这些转换为格式0D0A。
TextWriter.NewLine属性仅由WriteLine等方法使用,并控制作为调用的一部分附加的隐式换行符的格式。
Environment.NewLine
和TextWriter.NewLine
之间的区别在于Environment.NewLine是只读的,只是程序员要查询的。 (例如,这与Java不同,您可以使用System.setProperty("line.separator", x);
在C#中,您可以使用TextWriter.NewLine
进行书写时修改隐式换行符的格式,Environment.NewLine
初始化为TextReader.NewLine
。使用读取行的TextReader方法时,没有sw.Write("1\uf0f1\n2\ue0e1\n3\ud0d1\n".Replace("\n", Environment.NewLine));
属性。读者的隐式换行行为是在任何0x0A,0x0D或0D0A
正如勒内所指出的,原始问题可以通过写下来解决:
{{1}}