如何将文件读入保存CR / LF的字符串?

如果我问“如何将文件读成字符串”的问题,那么答案就很明显了。 然而 – 这里保留了CR / LF的捕获量。

问题是, File.ReadAllText这些字符。 StreamReader.ReadToEnd刚刚将LF转换为CR导致我进行了长时间的调查,我在相当明显的代码中有bug 😉

所以,简而言之,如果我有包含foo\n\r\nbar我想得到foo\n\r\nbar (即完全相同的内容),而不是foo barfoobarfoo\n\n\nbar 。 .Net空间中是否有一些可以使用的方式?

结果应该始终是单个字符串,包含整个文件。

你确定那些方法是剥夺你的角色的罪魁祸首吗?

我试着写一个快速测试; StreamReader.ReadToEnd保留所有换行符。

 string str = "foo\n\r\nbar"; using (Stream ms = new MemoryStream(Encoding.ASCII.GetBytes(str))) using (StreamReader sr = new StreamReader(ms, Encoding.UTF8)) { string str2 = sr.ReadToEnd(); Console.WriteLine(string.Join(",", str2.Select(c => ((int)c)))); } // Output: 102,111,111,10,13,10,98,97,114 // foo \n \r \nbar 

写入和读取临时文件时,可以获得相同的结果:

 string str = "foo\n\r\nbar"; string temp = Path.GetTempFileName(); File.WriteAllText(temp, str); string str2 = File.ReadAllText(temp); Console.WriteLine(string.Join(",", str2.Select(c => ((int)c)))); 

您的换行似乎在其他地方丢失了。

这段代码将保留LR和CR

 string r = File.ReadAllText(@".\TestData\TR120119.TRX", Encoding.ASCII); 

结果应该始终是单个字符串,包含整个文件。

它需要两个跃点。 第一个是File.ReadAllBytes()来获取文件中的所有字节 。 哪个不尝试翻译任何内容,您将获得文件中的原始数据,以便按原样保留怪异的行结尾。

但那是字节,你问了一个字符串。 所以第二跳是应用Encoding.GetString()将字节转换为字符串。 您要做的一件事就是选择正确的Encoding类,该类与编写该文件的程序使用的编码相匹配。 如果文件包含\n\r\n序列,并且您没有记录有关该文件的任何其他信息,那么该文件非常混乱,您最好的选择是使用Encoding.Default。 根据需要调整。

您可以使用File.ReadAllLines读取文件的内容,它将返回行的数组。 然后使用String.Join使用分隔符将行合并在一起。

 string[] lines = File.ReadAllLines(@"C:\Users\User\file.txt"); string allLines = String.Join("\r\n", lines); 

请注意,这将失去实际行终止符的精度。 例如,如果行仅以\n\r结尾,则生成的字符串allLines将用\r\n行终止符替换它们。

当然还有其他方法可以在不失去真正的EOL终结符的情况下实现这一点,但是ReadAllLines非常方便,因为它可以自己检测多种类型的文本编码,并且它也占用很少的代码行。

ReadAllText不返回回车符。

此方法打开一个文件,读取文件的每一行,然后将每一行添加为字符串的元素。 然后它关闭文件。 一行被定义为一系列字符,后跟一个回车符(’\ r’),一个换行符(’\ n’)或一个回车符后面紧跟一个换行符。 生成的字符串不包含终止回车符和/或换行符

来自MSDN – https://msdn.microsoft.com/en-us/library/ms143368(v=vs.110).aspx

这与接受的答案类似,但希望更多地说明问题。 sr.ReadToEnd()将读取所需的字节:

 string myFilePath = @"C:\temp\somefile.txt"; string myEvents = String.Empty; FileStream fs = new FileStream(myFilePath, FileMode.Open); StreamReader sr = new StreamReader(fs); myEvents = sr.ReadToEnd(); sr.Close(); fs.Close(); 

您甚至可以using级联using语句来执行这些using 。 但我想描述一下你写入该文件的方式将决定如何从myEvents字符串中读取内容,并且可能真的是问题所在。 我写信给我的文件是这样的:

 using System.Reflection; using System.IO; private static void RecordEvents(string someEvent) { string folderLoc = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (!folderLoc.EndsWith(@"\")) folderLoc += @"\"; folderLoc = folderLoc.Replace(@"\\", @"\"); // replace double-slashes with single slashes string myFilePath = folderLoc + "myEventFile.txt"; if (!File.Exists(myFilePath)) File.Create(myFilePath).Close(); // must .Close() since will conflict with opening FileStream, below FileStream fs = new FileStream(myFilePath, FileMode.Append); StreamWriter sr = new StreamWriter(fs); sr.Write(someEvent + Environment.NewLine); sr.Close(); fs.Close(); } 

然后我可以使用上面的代码来获取内容的字符串。 因为我正在进一步寻找单个字符串,所以我把这段代码放在那个代码之后,在那里:

 if (myEvents != String.Empty) // we have something { // (char)2660 is ♠ -- I could have chosen any delimiter I did not // expect to find in my text myEvents = myEvents.Replace(Environment.NewLine, ((char)2660).ToString()); string[] eventArray = myEvents.Split((char)2660); foreach (string s in eventArray) { if (!String.IsNullOrEmpty(s)) // do whatever with the individual strings from your file } } 

这很好用。 所以我知道myEvents必须保留Environment.NewLine字符,因为我能够用(char)2660替换它,并使用该字符对该字符串执行.Split()将其划分为各个段。