So, I have a problem:
text that I would like to read is stored in .xml file, but it contains parameters marked $PARAMETER_NAME$
(f.e. $UserName$
).
I also have Dictionary<string, string>
which contains all of the required key/value pairs.
I would like to deserialize the xml file, but I need to replace parameters with corresponding values.
The only solution I've came up with was to read the whole file and replace each value, but this approach consumes TOO much memory and is quite childish
Can I somehow override FileStream's Read()
method to replace the values on-read?
I've actually done this kind of thing before, to compare documents exported as PDF files as MD5s. I needed to make the stream ignore the creation time stamps present inside the pdf. The basic method is the following:
Read(byte[] buffer, int offset, int count)
, and implement it so it it reads the required length, plus, both before and after (as far as the file goes, of course), the length of that longest string. Once you have this longer range, search and replace the strings in it. The extra stuff you read before and after will make sure you catch all parameters. After replacing them, make sure to cut it down to the original requested size again.int ReadByte()
to call the full buffer-based read so it also catches these parameters.Note that since you're working with strings you might have some extra complications there concerning the encoding of the text in the xml file; if it's UTF-16, each character is two bytes, after all. Personally, if you know what input to expect, I'd give the encoding as parameter to the constructor; easier than having to add some kind of messy detection for it inside the writer.
This was a class I wrote for the PDF reading, but it only replaces the matches by empty strings of the same length.
You'll have to figure out how to get around your pointer desync problem, though, in case the read pointer is ever changed manually during a read. You never know how the internals of the xml parser handle it; they might occasionally look back to previous tags.
You'll probably have to do a full sweep of the file in advance, from your constructor, and let it make a full list of all offsets where you found a key, and the key on that location. That seems to be the only way to make a method to reliably adjust the requested read pointer to the correct actual offset in the file for any requested random access read.