У меня есть несколько файлов XML-файлов с незаконными символами (0x1 и т. Д.). Файлы сторонние, я не могу изменить процесс их написания.Как написать обтекатель потока «фильтр» для XML?
Я хотел бы обрабатывать эти файлы с помощью XmlReader
, но это взрывает эти незаконные символы.
Я мог читать файлы, отфильтровывать плохие символы, сохранять их, а затем обрабатывать их ... но это очень много ввода-вывода, и кажется, что это не должно быть ненужным.
То, что я хотел бы сделать что-то вроде этого:
using(var origStream = File.OpenRead(fileName))
using(var cleanStream = new CleansedXmlStream(origStream))
using(var streamReader = new StreamReader(cleanStream))
using(var xmlReader = XmlReader.Create(streamReader))
{
//do stuff with reader
}
Я попытался унаследовать от Stream
, но когда я добрался до реализации Read(byte[] buffer, int offset, int count)
я потерял некоторую уверенность. В конце концов, я планировал удалить символы, поэтому показалось, что счет будет выключен, и мне пришлось бы перевести каждый байт на char
, который казался дорогим (особенно на больших файлах), и я не понял, как это будет работать с Кодировка Unicode, но ответы на мои вопросы не были интуитивно очевидными.
Когда googling для «C# stream wrapper» или «поток фильтра C#», я не получаю удовлетворительных результатов. Возможно, я использую неправильные слова или описываю неправильную концепцию, поэтому я надеюсь, что сообщество SO может меня удержать.
Используя приведенный выше пример, что будет CleansedXmlStream
?
Вот что моя первая попытка была похожа:
public class CleansedXmlStream : Stream
{
private readonly Stream _baseStream;
public CleansedXmlStream(Stream stream)
{
this._baseStream = stream;
}
public new void Dispose()
{
if (this._baseStream != null)
{
this._baseStream.Dispose();
}
base.Dispose();
}
public override bool CanRead
{
get { return this._baseStream.CanRead; }
}
public override bool CanSeek
{
get { return this._baseStream.CanSeek; }
}
public override bool CanWrite
{
get { return this._baseStream.CanWrite; }
}
public override long Length
{
get { return this._baseStream.Length; }
}
public override long Position
{
get { return this._baseStream.Position; }
set { this._baseStream.Position = value; }
}
public override void Flush()
{
this._baseStream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
//what does this look like?
throw new NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
return this._baseStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
this._baseStream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
}
0x01 SOH. Потоковые классы по умолчанию кодируются ASCII. Я бы установил класс потока в UTF8. Попробуйте что-то вроде этого: StreamReader stream = new StreamReader (имя файла, Encoding.UTF8); – jdweng
@jdweng по [документам] (https://msdn.microsoft.com/en-us/library/yhfzs7at (v = vs.110) .aspx), 'new StreamReader (Stream)' по умолчанию соответствует UTF8, поэтому это будет не имеет значения. –
Возможно, вам нужно работать на более высоком уровне абстракции. «Поток» - это двоичные данные, тогда как ваши недопустимые символы являются результатом декодирования этих двоичных данных. Может быть, вам нужно украсить «TextReader», а не украшать «Поток»? –