跟踪流读取器线的位置

joh*_*nie 13 c# streamreader

大家好我需要做的是跟踪我从流阅读器中读取的行的位置当我说reader.ReadLine()我需要知道文件中该行的位置时我还希望能够从中读取文件我之前跟踪的位置.

这可能吗?如果是这样请协助.

非常感谢帮助

提前致谢.

Chr*_*ler 23

你可以这三种方式之一:

1)编写自己的StreamReader.这是一个很好的起点:如何知道文本文件中流读取器的位置(亚麻)?

2)StreamReader类有两个非常重要但私有的变量,称为charPos和charLen,用于定位实际的"读取"位置,而不仅仅是流的底层位置.您可以使用反射来获取此处建议的值

Int32 charpos = (Int32) s.GetType().InvokeMember("charPos", 
BindingFlags.DeclaredOnly | 
BindingFlags.Public | BindingFlags.NonPublic | 
BindingFlags.Instance | BindingFlags.GetField
 ,null, s, null); 

Int32 charlen= (Int32) s.GetType().InvokeMember("charLen", 
BindingFlags.DeclaredOnly | 
BindingFlags.Public | BindingFlags.NonPublic | 
BindingFlags.Instance | BindingFlags.GetField
 ,null, s, null);

return (Int32)s.BaseStream.Position-charlen+charpos;
Run Code Online (Sandbox Code Playgroud)

3)只需将整个文件读入字符串数组即可.像这样的东西:

char[] CRLF = new char[2] { '\n', '\r' };
TextReader tr = File.OpenText("some path to file");
string[] fileLines = tr.ReadToEnd().Split(CRLF);
Run Code Online (Sandbox Code Playgroud)

另一种可能性(与#3相同)是读取行并将行存储在数组中.如果要读取前一行,只需使用该数组.

  • 选项#2是我使用的,但代码是错误的.我目前使用的是:http://stackoverflow.com/a/17457085/530545 (3认同)
  • 当1024*N边界将扩展字符分成两部分时,您确定选项2)是否安全? (2认同)
  • 当使用的编码不会为字符到字节创建 1 对 1 编码时,选项 2 将无法正常工作。在此处查看我的解决方案:http://stackoverflow.com/a/22975649/718033(编辑:我的解决方案似乎与格兰杰的解决方案非常相似) (2认同)

Ser*_*vel 5

跟踪实际的 StreamReader 位置(以字节为单位):

readonly static FieldInfo charPosField = typeof(StreamReader).GetField("charPos", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
readonly static FieldInfo charLenField = typeof(StreamReader).GetField("charLen", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
readonly static FieldInfo charBufferField = typeof(StreamReader).GetField("charBuffer", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);

static long ActualPosition(StreamReader reader)
{
    var charBuffer = (char[])charBufferField.GetValue(reader);
    var charLen = (int)charLenField.GetValue(reader);
    var charPos = (int)charPosField.GetValue(reader);

    return reader.BaseStream.Position - reader.CurrentEncoding.GetByteCount(charBuffer, charPos, charLen-charPos);
}
Run Code Online (Sandbox Code Playgroud)

不客气。

  • 对于 .NET Core,所有字段名称都有下划线前缀,请参阅 https://source.dot.net/#System.Private.CoreLib/StreamReader.cs,b5fe1efcec14de32 (2认同)