首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Environment.NewLine和TextWriter.NewLine属性的用途是什么?

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

Stack Overflow用户
提问于 2013-08-04 09:57:16
回答 4查看 3.3K关注 0票数 0

我有一个奇怪的情况,我不明白与新行'\n'有关,我要发送到一个文件。新行似乎没有根据NewLine属性TextWriter和Environment来处理。这一守则表明:

代码语言:javascript
复制
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();

当我运行此命令时,控制台输出是

2 2

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

000000h: 31 EF 83 B1 0A 32 EE 83 A1 0A 33 ED 83 91 0A,1ƒ±2.2ƒ3탑。

很明显,API表示两个字符,当您查看文件时,只有一个字符。现在,当我查看TextWriter中写方法的描述时,它指示写方法没有用NewLine属性替换0A。那么,如果写方法没有考虑到这一点,那么拥有一个NewLine属性而不是两个属性有什么用呢?这些东西是干什么用的?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-08-05 07:47:45

在字符串中转义为\n的所有换行符都是单个字符的ASCII换行符( 0x0A ) (而不是Windows新行0D0A),并以0x0A的形式输出到写入器中的流,除非程序员采取明确步骤将字符串内的这些行转换为0D0A格式。

TextWriter.NewLine属性仅由WriteLine之类的方法使用,并控制作为调用一部分附加的隐式换行符的格式设置。

Environment.NewLine和TextWriter.NewLine的区别在于,Environment.NewLine是只读的,只供程序员查询。(例如,这与Java不同,在Java中,可以使用System.setProperty("line.separator", x);更改“系统范围”换行符的默认设置。

在C#中,您可以在使用初始化为Environment.NewLine的TextWriter.NewLine编写时修改隐式换行符的格式。当使用读取行的TextReader方法时,不存在TextReader.NewLine属性。读取器的隐式换行符行为是在任意0x0A、0x0D或0D0A处中断

正如雷内指出的,最初的问题可以通过写作来解决:

代码语言:javascript
复制
sw.Write("1\uf0f1\n2\ue0e1\n3\ud0d1\n".Replace("\n", Environment.NewLine));
票数 0
EN

Stack Overflow用户

发布于 2013-08-04 13:46:39

程序员有一个很长的历史,就是不同意将文本写入文件时应该如何编码。ASCII和Unicode在某种程度上帮助夷平了巴别塔。但是,一行的结尾所指的字符却从来没有达成一致。

  • Windows使用回车+行馈送控制代码。"\r\n"在C#代码中。
  • Unix口味只使用一行提要控制代码,'\n'在C#代码中。
  • 苹果过去只使用单一的回车控制代码,'\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()而不是写():

代码语言:javascript
复制
  sw.WriteLine("1\uf0f1");
  sw.WriteLine("2\ue0e1");
  sw.WriteLine("3\ud0d1"); 

这也使您的代码具有良好的可读性,在运行时也不会慢。如果您想保留一行,那么可以使用复合格式:

代码语言:javascript
复制
  sw.Write("1\uf0f1{0}2\ue0e1{0}3\ud0d1{0}", Environment.NewLine);
票数 6
EN

Stack Overflow用户

发布于 2013-08-04 09:59:28

如果选择通过向流线器发送\n来生成“行中断”,那么框架就不可能对此进行干预。如果希望框架遵守NewLine属性,请使用写入器的WriteLine方法,并设置写入器的NewLine属性。

修改您的代码如下:

代码语言:javascript
复制
sw.NewLine = Environment.NewLine; // StreamWriter uses \r\n by default

sw.WriteLine("1\uf0f1")
sw.WriteLine("2\ue0e1");
sw.WriteLine("3\ud0d1");

或者有一个自定义StreamWriter来重写写方法:

代码语言:javascript
复制
public class MyStreamWriter:StreamWriter
{
    public MyStreamWriter(Stream s):base(s)
    {
    }

    public override void Write(string s)
    {
        base.Write(s.Replace("\n",Environment.NewLine));
    }   
}

或者,如果您只想处理一行:

代码语言:javascript
复制
sw.Write("1\uf0f1\n2\ue0e1\n3\ud0d1\n".Replace("\n", Environment.NewLine));
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18041729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档