8

如果我问“如何将文件读入字符串”这个问题,答案将是显而易见的。但是 - 这是保留 CR/LF 的问题。

问题是,File.ReadAllText去掉这些字符。StreamReader.ReadToEnd刚刚为我将 LF 转换为 CR,这导致我在很明显的代码中有错误的地方进行了长时间的调查;-)

所以,简而言之,如果我有包含foo\n\r\nbar我想要获取的文件foo\n\r\nbar(即完全相同的内容),则不是foo bar,foobarfoo\n\n\nbar. .Net 空间中是否有一些现成的使用方式?

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

4

6 回答 6

10

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

我试图写一个快速测试;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
//           f   o   o \n \r \n  b  a   r

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

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

看来您的换行符在其他地方迷路了。

于 2012-11-22T22:19:01.747 回答
6

这段代码将保留 LR 和 CR

string r = File.ReadAllText(@".\TestData\TR120119.TRX", Encoding.ASCII);
于 2014-04-11T13:28:56.840 回答
2

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

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

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

于 2012-11-22T22:14:04.577 回答
1

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

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

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

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

于 2012-11-22T22:21:04.703 回答
0

ReadAllText 不返回回车符。

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

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

于 2016-10-29T07:36:17.233 回答
0

这类似于接受的答案,但希望更重要。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语句中执行这些操作。但我想首先描述您写入该文件的方式将如何决定如何从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()操作,以将其划分为各个段。

于 2016-11-23T23:53:24.407 回答