-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Proposal: StringStream (a Stream that wraps a string) #46663
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Ooh, I was really hoping for something close: a TextReaderStream that encodes as it reads and a TextWriterStream that decodes as it writes. The equivalent of StringStream would then be All my use cases are based on TextReaderStream or TextWriterStream. None are actually based on strings, so I wouldn't actually be able to use a StringStream. |
Would this help avoid byte array allocations in places such as Or |
Interesting concept. I could see this being useful for networking scenarios. Some API-level suggestions: (a) the bufferCharCount ctor parameter probably isn't needed since the underlying Implementation-wise, it'd be nice to special-case UTF-8 since it's going to be the most common and can be optimized both in terms of performance and in killing unneeded state instance fields. @KirillOsenkov I don't think this API would be useful in |
Nice proposal! 😄 Also thought I'd mention, while not exactly the same since it eg. doesn't support a custom encoding and it's not part of the BCL, as a temporary alternative solution this can be achieved with APIs from the using Stream stream = "Hello world".AsMemory().AsBytes().AsStream();
// Use the stream here to read directly from string data EDIT: to clarify, the EDIT 2: this has now been publicly released since March 2021 (.NET API docs link). |
Maybe construction should happen through factory methods. That would allow returning a specialized class for UTF8 and other special cases. I also think that the |
There are plenty of types that currently don't force you to think about @stephentoub @GrabYourPitchforks @bartonjs, should that be a policy for new APIs? |
I agree with @GSPP that for StringStream specifically you should be required to specify the encoding; unlike something like StreamReader which by default tries to infer an encoding based on the BOM at the beginning of the file, for StringStream you're giving it something that has no BOM and you're asking it for bytes, which requires it to go through some Encoding to produce. We could say that strings are UTF16 and so the default is UTF16, but I expect that's unlikely to be what most consumers actually want and would lead us to a pit of failure. |
Background and Motivation
I've discovered over the years that providing string-based content via a
Stream
is a common requirement. The conventional wisdom (as indicated by highly-voted Stack Overflow questions and answers, message board posts, etc.) appears to be to convert the string to a byte array using anEncoding
and then wrap it with aMemoryStream
. This likely works fine for small strings or other situations where performance and memory aren't of great concern, but is likely not an optimal approach given larger strings. Instead I'd propose aStringStream
class be provided in-the-box that correctly provides a givenstring
(orReadOnlyMemory<char>
) as aStream
while buffering chunks in a reusable buffer to reduce the overall memory footprint and avoid allocating an entirebyte[]
to contain the fully-encoded representation at once.Proposed API
As with most other
Stream
derived classes, the API surface of aStringStream
would be essentially identical. It might contain the following constructors as well as additional members (otherStream
members omitted for brevity):To further help explain the concept, a sample (possibly naïve) implementation can be found at: https://gist.github.com/daveaglick/e49145d650ea3a4dbc3b6d0f8482fd37 (thanks to @benaadams for several ideas here).
Usage Examples
Since the
StringStream
is intended to derive from theStream
class and conform to it's API, usage would be similar to any otherStream
:Alternative Designs
As previously mentioned, similar functionality is often implemented by wrapping a fully-encoded representation of the string with a
MemoryStream
.C++ has a
stringstream
class that appears to be more of an iterator over a stack of strings than an actual C#-like stream (and as far as I can tell it makes no attempt to handle character encoding).Risks
Anything dealing with character encoding has the potential for edge cases and challenging logic, so care would need to be taken that all encodings are handled or at least well documented (such as preamble, fallback, etc.).
The text was updated successfully, but these errors were encountered: