简体   繁体   English

使用StreamReader.Peek与StreamReader读取多行

[英]Read multiple lines with StreamReader with StreamReader.Peek

Let's say I have the following file format (Key value pairs): 假设我有以下文件格式(键值对):

Objec1tKey: Object1Value
Object2Key: Object2Value
Object3Key: Object3Value
Object4Key: Object4Value1
Object4Value2
Object4Value3
Object5Key: Object5Value
Object6Key: Object6Value

I'm reading this line by line with StreamReader . 我正在用StreamReader逐行阅读此内容。 for the objects 1, 2, 3, 5 and 6 it wouldn't be a problem because the whole object is on one line, so it's possible to process the object. 对于对象1、2、3、5和6,这不会有问题,因为整个对象都在一行上,因此可以处理该对象。

But for object 4 I need to process multiple lines. 但是对于对象4,我需要处理多行。 can I use Peek for this? 我可以为此使用Peek吗? ( MSDN for Peek: Returns the next available character but does not consume it. ). 用于Peek的MSDN:返回下一个可用字符,但不使用它。 )。 Is there a method like Peek which returns the next line and not the character? 是否有类似Peek的方法返回下一行而不是字符?

If I can use Peek , then my question is, can I use Peek two times so I can read the two next lines (or 3) until I know there is a new object (obect 5) to be processed? 如果可以使用Peek ,那么我的问题是,可以两次使用Peek以便读取下两行(或3行),直到我知道有一个新对象(对象5)要处理?

I would strongly recommend that you separate the IO from the line handling entirely. 我强烈建议您将IO与线路处理完全分开。

Instead of making your processing code use a StreamReader , pass it either an IList<string> or an IEnumerable<string> ... if you use IList<string> that will make it really easy to just access the lines by index (so you can easily keep track of "the key I'm processing started at line 5" or whatever), but it would mean either doing something clever or reading the whole file in one go. 与其让您的处理代码使用StreamReaderStreamReader将其传递给IList<string>IEnumerable<string> ...(如果您使用IList<string> ,这将使通过索引访问行确实非常容易(因此,可以轻松地跟踪“我正在处理的密钥是从第5行开始的”或其他内容),但这意味着要么做一些聪明的事情,要么一次性读取整个文件。

If it's not a big file, then just using File.ReadAllLines is going to be the very simplest way of reading a file as a list of lines. 如果不是大文件,则仅使用File.ReadAllLines将是读取文件作为行列表的最简单方法。

If it is a big file, use File.ReadLines to obtain an IEnumerable<string> , and then your processing code needs to be a bit smarter... for example, it might want to create a List<string> for each key that it processes, containing all the lines for that key - and let that list be garbage collected when you read the next key. 如果它一个大文件,请使用File.ReadLines获得IEnumerable<string> ,然后您的处理代码需要更聪明……例如,它可能想要为每个要创建的键创建一个List<string>它进行处理,包含该键的所有行-并在您读取下一个键时将该列表进行垃圾回收。

There is now way to use Peek multiple time as you thing, because it will always return only "top" character in stream. 现在,您可以使用多次使用Peek方式,因为它总是在流中仅返回“顶部”字符。 It just read it but "not send" to stream information that it was read. 它只是读取它,但“不发送”以流式传输已读取的信息。

To sum up pointer to stream after Peek stays in same place. 总结在Peek停留在同一位置后要指向流的指针。

If you use for example FileStream you can use Seek for going back, but you didn't precise what type of stream are you using. 例如,如果使用FileStream ,则可以使用Seek进行回溯,但是您并不确定使用的是哪种类型的流。

You could do something like this: 您可以执行以下操作:

            List<MyObject> objects = new List<MyObject>();
            using (StreamReader sr = new StreamReader(aPath))
            {
                MyObject curObj;
                while (!sr.EndOfStream)
                {
                    string line = sr.ReadLine();
                    if (line.IndexOf(':') >= 0) // or whatever identify the beginning of a new object
                    {
                        curObj = new MyObject(line);
                        objects.Add(curObj);
                    }
                    else
                        curObj.AddAttribute(line);
                }
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM