That solution looks altogether workable to me.
One nitpick: I find that when I have to store different types of things in a uniform way, and there are only a small, non-expandable number of types that can exist, I'd rather have separate methods readInt(), readString() etc. and live with a small amount of duplication to specifyingrather than specify the generic parameter on every access. At least, I would write "syntactic sugar" wrappers in that style. But that really is a question of what you consider more readable. Obviously, if there are an unbounded number of types that you have to support, the generic solution is the way to go.