首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C# StreamReader,用于自定义分隔符的"ReadLine“

C# StreamReader,用于自定义分隔符的"ReadLine“
EN

Stack Overflow用户
提问于 2012-03-26 21:32:52
回答 4查看 12K关注 0票数 20

除了自定义(字符串)分隔符之外,使用StreamReader.ReadLine()方法的功能的最佳方式是什么?

我想做一些类似的事情:

代码语言:javascript
复制
String text;
while((text = myStreamReader.ReadUntil("my_delim")) != null)
{
   Console.WriteLine(text);
}

我试着用Peek()StringBuilder做我自己的,但是效率太低了。我正在寻找建议或可能的开源解决方案。

谢谢。

编辑

我应该早点澄清这一点……我已经看过this answer了,然而,我不希望将整个文件读入内存。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-03-28 02:18:45

我想我应该发布我自己的解决方案。它似乎工作得很好,代码也相对简单。请随时发表评论。

代码语言:javascript
复制
public static String ReadUntil(this StreamReader sr, String delim)
{
    StringBuilder sb = new StringBuilder();
    bool found = false;

    while (!found && !sr.EndOfStream)
    {
       for (int i = 0; i < delim.Length; i++)
       {
           Char c = (char)sr.Read();
           sb.Append(c);

           if (c != delim[i])
               break;

           if (i == delim.Length - 1)
           {
               sb.Remove(sb.Length - delim.Length, delim.Length);
               found = true;
           }
        }
     }

     return sb.ToString();
}
票数 3
EN

Stack Overflow用户

发布于 2012-03-26 23:09:51

这段代码适用于任何字符串分隔符。

代码语言:javascript
复制
public static IEnumerable<string> ReadChunks(this TextReader reader, string chunkSep)
{
    var sb = new StringBuilder();

    var sepbuffer = new Queue<char>(chunkSep.Length);
    var sepArray = chunkSep.ToCharArray();

    while (reader.Peek() >= 0)
    {
        var nextChar = (char)reader.Read();
        if (nextChar == chunkSep[sepbuffer.Count])
        {
            sepbuffer.Enqueue(nextChar);
            if (sepbuffer.Count == chunkSep.Length)
            {
                yield return sb.ToString();
                sb.Length = 0;
                sepbuffer.Clear();
            }
        }
        else
        {
            sepbuffer.Enqueue(nextChar);
            while (sepbuffer.Count > 0)
            {
                sb.Append(sepbuffer.Dequeue());
                if (sepbuffer.SequenceEqual(chunkSep.Take(sepbuffer.Count)))
                    break;
            }
        }
    }
    yield return sb.ToString() + new string(sepbuffer.ToArray());
}

免责声明:

我对此做了一些测试,实际上比ReadLine方法慢,但我怀疑这是因为ReadLine方法中可以避免的入队/出队/序列相等调用(因为分隔符始终是\r\n)。

再说一次,我做了一些测试,它应该可以工作,但不要认为它是完美的,请随意更正它。;)

票数 1
EN

Stack Overflow用户

发布于 2012-03-26 23:28:36

这是我在需要的地方使用的一个简单的解析器(通常如果流不是最重要的,只读和.Split做的工作),不是太优化,但应该工作得很好:

(它更像是一种Split方法--下面有更多注释)

代码语言:javascript
复制
    public static IEnumerable<string> Split(this Stream stream, string delimiter, StringSplitOptions options)
    {
        var buffer = new char[_bufffer_len];
        StringBuilder output = new StringBuilder();
        int read;
        using (var reader = new StreamReader(stream))
        {
            do
            {
                read = reader.ReadBlock(buffer, 0, buffer.Length);
                output.Append(buffer, 0, read);

                var text = output.ToString();
                int id = 0, total = 0;
                while ((id = text.IndexOf(delimiter, id)) >= 0)
                {
                    var line = text.Substring(total, id - total);
                    id += delimiter.Length;
                    if (options != StringSplitOptions.RemoveEmptyEntries || line != string.Empty)
                        yield return line;
                    total = id;
                }
                output.Remove(0, total);
            }
            while (read == buffer.Length);
        }

        if (options != StringSplitOptions.RemoveEmptyEntries || output.Length > 0)
            yield return output.ToString();
    }

...and如果需要,可以简单地切换到字符分隔符,只需替换

代码语言:javascript
复制
while ((id = text.IndexOf(delimiter, id)) >= 0)

...with

代码语言:javascript
复制
while ((id = text.IndexOfAny(delimiters, id)) >= 0)

(用id++代替id+=和一个签名this Stream stream, StringSplitOptions options, params char[] delimiters)

...also删除空等。

希望能有所帮助

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9873097

复制
相关文章

相似问题

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