C#Streamreader - 仅在{CR} {LF}中断

时间:2016-07-12 15:19:08

标签: c# .net text-files streamreader flat-file

我正在尝试在执行复杂的SSIS插入包之前计算文本文件中的行数(以与控制文件进行比较)。

目前我正在使用一个StreamReader,它正在打破一条嵌入新行的{LF}行,而SSIS正在使用{CR} {LF}(正确),因此计数不合理。

有没有人知道另一种方法,我可以根据{CR} {LF}换行计算文件中的行数?

提前致谢

4 个答案:

答案 0 :(得分:3)

遍历文件并计算CRLF的数量。

非常简单的实施:

public int CountLines(Stream stream, Encoding encoding)
{
    int cur, prev = -1, lines = 0;
    using (var sr = new StreamReader(stream, encoding, false, 4096, true))
    {
        while ((cur = sr.Read()) != -1)
        {
            if (prev == '\r' && cur == '\n')
                lines++;

            prev = cur;
        }
    }

    //Empty stream will result in 0 lines, any content would result in at least one line
    if (prev != -1)
        lines++;

    return lines;
}

使用示例:

using(var s = File.OpenRead(@"<your_file_path>"))
    Console.WriteLine("Found {0} lines", CountLines(s, Encoding.Default));

实际上它是字符串任务中的查找子字符串。可以使用更通用的算法。

答案 1 :(得分:2)

{CR} {LF}是理想的。真的不能说哪个是正确的。

由于ReadLine剥离了你不知道的行尾。

使用StreamReader.Read Method ()并查找13,然后是10
它返回Int

答案 2 :(得分:2)

这是一种非常懒惰的方式......这会将整个文件读入内存。

var cnt = File.ReadAllText("yourfile.txt")
              .Split(new[] { "\r\n" }, StringSplitOptions.None)
              .Length;

答案 3 :(得分:0)

这是一种扩展方法,它仅使用行分隔符{Cr} {Lf}而不是{LF}读取行。您可以依靠它。

var count=  new StreamReader(@"D:\Test.txt").ReadLinesCrLf().Count()

但是也可以使用它来读取文件,由于正常的StreamReader.ReadLine在{Cr} {Lf}和{LF}上都中断,因此有时很有用。可以在任何TextReader上使用,并且可以流式传输(文件大小不是问题)。

    public static IEnumerable<string> ReadLinesCrLf(this TextReader reader, int bufferSize = 4096)
    {
        StringBuilder lineBuffer = null;

        //read buffer            
        char[] buffer = new char[bufferSize];
        int charsRead;

        var previousIsLf = false;

        while ((charsRead = reader.Read(buffer, 0, bufferSize)) != 0)
        {
            int bufferIndex = 0;
            int writeIdx = 0;
            do
            {
                var currentChar = buffer[bufferIndex];
                switch (currentChar)
                {
                    case '\n':
                        if (previousIsLf)
                        {
                            if (lineBuffer == null)
                            {
                                //return from current buffer writeIdx could be higher than 0 when multiple rows are in the buffer                                            
                                yield return new string(buffer, writeIdx, bufferIndex - writeIdx - 1);
                                //shift write index to next character that will be read
                                writeIdx = bufferIndex + 1;
                            }
                            else
                            {
                                Debug.Assert(writeIdx == 0, $"Write index should be 0, when linebuffer != null");
                                lineBuffer.Append(buffer, writeIdx, bufferIndex - writeIdx);
                                Debug.Assert(lineBuffer.ToString().Last() == '\r',$"Last character in linebuffer should be a carriage return now");
                                lineBuffer.Length--;
                                //shift write index to next character that will be read
                                writeIdx = bufferIndex + 1;
                                yield return lineBuffer.ToString();
                                lineBuffer = null;
                            }
                        }

                        previousIsLf = false;
                        break;
                    case '\r':
                        previousIsLf = true;
                        break;
                    default:
                        previousIsLf = false;
                        break;

                }


                bufferIndex++;
            } while (bufferIndex < charsRead);
            if (writeIdx < bufferIndex)
            {
                if (lineBuffer == null) lineBuffer = new StringBuilder();
                lineBuffer.Append(buffer, writeIdx, bufferIndex - writeIdx);
            }
        }
        //return last row
        if (lineBuffer != null && lineBuffer.Length > 0) yield return lineBuffer.ToString();
    }