How to reset position in StringReader to begining of String?
Asked Answered
O

5

6

I have the following code:

StringReader contentReader = new StringReader(this.dataContent.ToString());

After I parse my DataContent, I need to reset the poistion of the contentReader to begining of the string. How do I do it? I dont see a set poistion option in StringReader

Orpine answered 4/6, 2014 at 21:12 Comment(2)
Just for curiosity, why you need to reposition it to the start?Electrophilic
@Electrophilic - Any situation where a stream needs to be read twice. For example, if parsing as XML, and that parse fails (malformed XML), might want to pass the string (and error code) to different code. [In my case, simply to print an error message that includes beginning 100 characters of the string. To help with debugging. Maybe it wasn't XML. Maybe it is gibberish due to incorrectly interpreting encoding format.]Plano
S
10

Set it to a new instance of StringReader. I don't believe you can change the position of an existing one.

contentReader = new StringReader(this.dataContent.ToString());

Sedgewinn answered 4/6, 2014 at 21:16 Comment(0)
T
5

Another option would be to load the string into a MemoryStream then use a StreamReader to iterate over it. MemoryStream definitely supports position resets on a memory stream.

String data = "Hello! My name it Inigo Montoya.";
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
{
    using (StreamReader reader = new StreamReader(stream))
    {
        // Do your parsing here using the standard StreamReader methods.
        // They should be fairly comparable to StringReader.

        // When all done, reset stream position to the beginning.
        stream.Seek(0, SeekOrigin.Begin);
    }
}
Tussle answered 4/6, 2014 at 23:21 Comment(3)
You must call reader.DiscardBufferedData() after setting the stream position. msdn.microsoft.com/en-us/library/…Conservatism
@StevenLiekens: reader.Flush() is another option. However, both of these methods are only needed if the stream has been written to. In this instance neither call is needed.Tussle
There is no StreamReader.Flush(). Only DiscardBufferedData(). Which you have to call after seeking, because the reader will read any buffered bytes before hitting the stream again if you don't.Conservatism
C
4

The StringReader keeps track of its position within the string with a private int field called _pos, if you want to reset it you can use a simple extension method like this:

public static void Reset(this StringReader reader)
{
    reader.GetType()
          .GetField("_pos", BindingFlags.NonPublic | BindingFlags.Instance)
          .SetValue(reader, 0);
}

And a test method:

[Test]
public void Reset()
{
    const string random = "this is a test string";
    using(var reader = new StringReader(random))
    {
        Assert.AreEqual(random, reader.ReadToEnd());
        Assert.IsEmpty(reader.ReadToEnd());

        reader.Reset();
        Assert.AreEqual(random, reader.ReadToEnd());
        Assert.IsEmpty(reader.ReadToEnd());
    }
}
Chifley answered 1/5, 2018 at 8:45 Comment(0)
A
1

You can use extension method for the StreamReader and handle it by yourself:

public static class SRExtentions
{
    public static void ResetToBeginning(this StringReader reader)
    {
        SetPrivateField(reader, "_pos", 0);
    }

    private static void SetPrivateField(this object obj, string name, object value)
    {
        BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
        Type type = obj.GetType();
        FieldInfo field = type.GetField(name, flags);
        field.SetValue(obj, value);
    }
}
Aegaeon answered 3/8, 2022 at 20:16 Comment(0)
H
-1

See also a similar question : How do you reset a C# .NET TextReader cursor back to the start point?

But as Matthew said, the solution is probably to simply create a new one.

Hufford answered 4/6, 2014 at 21:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.