C# 覆盖StreamReader';s读线法
我正试图覆盖StreamReader的ReadLine方法,但由于无法访问某些私有变量,所以很难覆盖。这是可能的,还是我应该编写自己的StreamReader类?假设您希望自定义StreamReader可以在任何可以使用TextReader的地方使用,通常有两个选项C# 覆盖StreamReader';s读线法,c#,streamreader,C#,Streamreader,我正试图覆盖StreamReader的ReadLine方法,但由于无法访问某些私有变量,所以很难覆盖。这是可能的,还是我应该编写自己的StreamReader类?假设您希望自定义StreamReader可以在任何可以使用TextReader的地方使用,通常有两个选项 从StreamReader继承并重写希望以不同方式工作的函数。在您的情况下,这将是StreamReader.ReadLine 从TextReader继承并根据您的需求完全实现阅读器功能 注意:对于上面的选项2,您可以维护对Strea
ReadLine()
实现仅用于演示目的,并不打算成为健壮或完整的实现
class CustomStreamReader : StreamReader
{
public CustomStreamReader(Stream stream)
: base(stream)
{
}
public override string ReadLine()
{
int c;
c = Read();
if (c == -1)
{
return null;
}
StringBuilder sb = new StringBuilder();
do
{
char ch = (char)c;
if (ch == ',')
{
return sb.ToString();
}
else
{
sb.Append(ch);
}
} while ((c = Read()) != -1);
return sb.ToString();
}
}
您会注意到,我只是使用StreamReader.Read()方法从流中读取字符。虽然与直接使用内部缓冲区相比,绝对没有共振峰那么明显,但是Read()
方法确实使用了内部缓冲区,因此仍然应该产生相当好的性能,但这需要测试以确认
为了好玩,这里有一个选项2的示例。我使用封装的StreamReader来减少实际代码,这根本没有经过测试
class EncapsulatedReader : TextReader
{
private StreamReader _reader;
public EncapsulatedReader(Stream stream)
{
_reader = new StreamReader(stream);
}
public Stream BaseStream
{
get
{
return _reader.BaseStream;
}
}
public override string ReadLine()
{
int c;
c = Read();
if (c == -1)
{
return null;
}
StringBuilder sb = new StringBuilder();
do
{
char ch = (char)c;
if (ch == ',')
{
return sb.ToString();
}
else
{
sb.Append(ch);
}
} while ((c = Read()) != -1);
return sb.ToString();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_reader.Close();
}
base.Dispose(disposing);
}
public override int Peek()
{
return _reader.Peek();
}
public override int Read()
{
return _reader.Read();
}
public override int Read(char[] buffer, int index, int count)
{
return _reader.Read(buffer, index, count);
}
public override int ReadBlock(char[] buffer, int index, int count)
{
return _reader.ReadBlock(buffer, index, count);
}
public override string ReadToEnd()
{
return _reader.ReadToEnd();
}
public override void Close()
{
_reader.Close();
base.Close();
}
}
假设您希望自定义StreamReader可以在任何可以使用TextReader的地方使用,通常有两个选项
ReadLine()
实现仅用于演示目的,并不打算成为健壮或完整的实现
class CustomStreamReader : StreamReader
{
public CustomStreamReader(Stream stream)
: base(stream)
{
}
public override string ReadLine()
{
int c;
c = Read();
if (c == -1)
{
return null;
}
StringBuilder sb = new StringBuilder();
do
{
char ch = (char)c;
if (ch == ',')
{
return sb.ToString();
}
else
{
sb.Append(ch);
}
} while ((c = Read()) != -1);
return sb.ToString();
}
}
您会注意到,我只是使用StreamReader.Read()方法从流中读取字符。虽然与直接使用内部缓冲区相比,绝对没有共振峰那么明显,但是Read()
方法确实使用了内部缓冲区,因此仍然应该产生相当好的性能,但这需要测试以确认
为了好玩,这里有一个选项2的示例。我使用封装的StreamReader来减少实际代码,这根本没有经过测试
class EncapsulatedReader : TextReader
{
private StreamReader _reader;
public EncapsulatedReader(Stream stream)
{
_reader = new StreamReader(stream);
}
public Stream BaseStream
{
get
{
return _reader.BaseStream;
}
}
public override string ReadLine()
{
int c;
c = Read();
if (c == -1)
{
return null;
}
StringBuilder sb = new StringBuilder();
do
{
char ch = (char)c;
if (ch == ',')
{
return sb.ToString();
}
else
{
sb.Append(ch);
}
} while ((c = Read()) != -1);
return sb.ToString();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_reader.Close();
}
base.Dispose(disposing);
}
public override int Peek()
{
return _reader.Peek();
}
public override int Read()
{
return _reader.Read();
}
public override int Read(char[] buffer, int index, int count)
{
return _reader.Read(buffer, index, count);
}
public override int ReadBlock(char[] buffer, int index, int count)
{
return _reader.ReadBlock(buffer, index, count);
}
public override string ReadToEnd()
{
return _reader.ReadToEnd();
}
public override void Close()
{
_reader.Close();
base.Close();
}
}
这门课可以帮助你
public class MyStreamReader : System.IO.StreamReader
{
public MyStreamReader(string path)
: base(path)
{
}
public override string ReadLine()
{
string result = string.Empty;
int b = base.Read();
while ((b != (int)',') && (b > 0))
{
result += this.CurrentEncoding.GetString(new byte[] { (byte)b });
b = base.Read();
}
return result;
}
}
这门课可以帮助你
public class MyStreamReader : System.IO.StreamReader
{
public MyStreamReader(string path)
: base(path)
{
}
public override string ReadLine()
{
string result = string.Empty;
int b = base.Read();
while ((b != (int)',') && (b > 0))
{
result += this.CurrentEncoding.GetString(new byte[] { (byte)b });
b = base.Read();
}
return result;
}
}
试试这个,我写这个是因为我有一些非常大的“|”分隔文件,\r\n在某些列中,我需要使用\r\n作为行的结尾分隔符。我试图使用SSIS包导入一些文件,但由于文件中的一些损坏数据,我无法导入。该文件超过5 GB,因此太大,无法打开并手动修复。我通过浏览许多论坛来了解流是如何工作的,并最终找到了一个解决方案,该解决方案读取文件中的每个字符,并根据我添加到其中的定义吐出行。这是在命令行应用程序中使用的,附带帮助:)。我希望这能帮助其他人,我还没有找到一个像其他地方一样的解决方案,尽管这些想法是受这个论坛和其他论坛的启发。这不会修复文件,它只会分割文件。。。请注意,这仍在进行中:) 班级计划 { 静态长文件位置=0; 静态void Main(字符串[]参数) { //检查传入的信息 if(args.Any()) { 如果(参数[0]=“/?”) { var message=“将文件拆分为更小的部分”; 消息+=“\n”; 消息+=“\n”; 消息+=“拆分文件[sourceFileName][destinationFileName][RowBatchAmount][FirstRowHashHeader]”; 消息+=“\n”; 消息+=“\n”; 消息+=“[sourceFileName](字符串)必需”; 消息+=“\n”; 消息+=“[destinationFileName](字符串)将默认为与sourceFileName相同的位置”; 消息+=“\n”; 消息+=“[RowBatchAmount](INT)将创建包含这么多行的文件”; 消息+=“\n”; 消息+=“[FirstRowHashHeader](真/假)将向每个新文件添加标题行”; 控制台写入线(消息); } 其他的 { 字符串sourceFileName=args[0]; 字符串destFileLocation=args.Cou