How to reset position in StringReader to begining of String?

6.2k Views Asked by At

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

5

There are 5 best solutions below

0
On BEST ANSWER

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

0
On

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.

3
On

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);
    }
}
0
On

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

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