Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C Streamreader-仅在{CR}{LF}上中断_C#_.net_Text Files_Streamreader_Flat File - Fatal编程技术网

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

C# C Streamreader-仅在{CR}{LF}上中断,c#,.net,text-files,streamreader,flat-file,C#,.net,Text Files,Streamreader,Flat File,在执行复杂的SSIS插入包之前,我试图计算文本文件中要与控制文件进行比较的行数 目前,我正在使用StreamReader,它正在断开一行,并在新行中嵌入一个{LF},而SSI正在正确使用{CR}{LF},因此计数没有累计 有人知道这样做的另一种方法吗?我可以只根据{CR}{LF}换行来计算文件中的行数 提前感谢{CR}{LF}是需要的。真的说不出哪个是对的 因为ReadLine从行尾剥离,所以您不知道 使用并查找13,然后是10 它返回Int{CR}{LF}是所需的。真的说不出哪个是对的 因为R

在执行复杂的SSIS插入包之前,我试图计算文本文件中要与控制文件进行比较的行数

目前,我正在使用StreamReader,它正在断开一行,并在新行中嵌入一个{LF},而SSI正在正确使用{CR}{LF},因此计数没有累计

有人知道这样做的另一种方法吗?我可以只根据{CR}{LF}换行来计算文件中的行数


提前感谢

{CR}{LF}是需要的。真的说不出哪个是对的

因为ReadLine从行尾剥离,所以您不知道

使用并查找13,然后是10
它返回Int

{CR}{LF}是所需的。真的说不出哪个是对的

因为ReadLine从行尾剥离,所以您不知道

使用并查找13,然后是10
它返回Int

这里有一个非常懒惰的方法。。。这将把整个文件读入内存

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

这是一个相当懒惰的方法。。。这将把整个文件读入内存

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

迭代文件并计算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));

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

迭代文件并计算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));

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

这里有一个扩展方法,它只读取带有行分隔符{Cr}{Lf}的行,而不读取{Lf}。你可以数一数

var count=  new StreamReader(@"D:\Test.txt").ReadLinesCrLf().Count()
但也可以将其用于读取文件,有时会很有用,因为正常的StreamReader.ReadLine在{Cr}{Lf}和{Lf}上都会中断。可用于任何文本阅读器和works流媒体文件大小不是问题

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

这里是一个扩展方法,它只读取带有行分隔符{Cr}{Lf}的行,而不读取{Lf}。你可以数一数

var count=  new StreamReader(@"D:\Test.txt").ReadLinesCrLf().Count()
但也可以将其用于读取文件,有时会很有用,因为正常的StreamReader.ReadLine在{Cr}{Lf}和{Lf}上都会中断。可用于任何文本阅读器和works流媒体文件大小不是问题

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

你可以自己读取文件,然后按照自己的意愿进行拆分;只要读取字节,当您遇到一个{CR}{LF}时,就开始一行新的代码。^-这就是StreamReader在封面下的工作方式。它在CR,LF和CRLF上分开也许这有帮助。。快速自定义流读取器也可以解决其他断行问题。请参阅post@Clint:Reading bytes不是一件特别安全的事情,除非您确定文件编码是单字节字符集。事实上,如果文件是16位Unicode,则CR/LF对以4个字节编码:0x00、0x0D、0x00、0x0A。现在,如果您使用StreamReader以文本形式打开它并读取字符。你可以自己读取文件,然后按照自己的意愿进行拆分;只要读取字节,当您遇到一个{CR}{LF}时,就开始一行新的代码。^-这就是StreamReader在封面下的工作方式。它在CR,LF和CRLF上分开也许这有帮助。。快速自定义流读取器也可以解决其他断行问题。请参阅post@Clint:Reading bytes不是一件特别安全的事情,除非您确定文件编码是单字节字符集。事实上,如果文件是16位Unicode,则CR/LF对以4个字节编码:0x00、0x0D、0x00、0x0A。现在,如果您使用StreamReader以文本形式打开它并读取字符。由于大小的原因,一次读取整个文件不是一个选项,但对于较小的文件来说是一个不错的解决方案。由于大小的原因,一次读取整个文件不是一个选项,但是对于较小的文件来说是一个不错的解决方案。希望您不要遇到一个Unicode文件,其中一个字符的最后一个字节等于CR,而下一个字符的第一个字节是LF。您确实应该在回答中注意到,此解决方案不能保证适用于任何Unicode编码。@JimMischel感谢您指出这一点。原始答案在任何多字节编码上都会失败。修复了它。希望您不会遇到一个Unicode文件,其中一个字符的最后一个字节等于CR,而下一个字符的第一个字节等于LF。您确实应该在回答中注意到,此解决方案不能保证适用于任何Unicode编码。@JimMischel感谢您指出这一点。原始答案在任何多字节编码上都会失败。修好了。