-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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: Adding ArraySegment-based methods to the System.IO namespace #16635
Comments
Before adding a bunch of additional dotnet/roslyn#120 |
I think it's fair to say that we will either add support for slices or arraysegment. Let's hope that for slices :-) |
@justinvp @KrzysztofCwalina How would that work in terms of the existing API though? As far as I can see, |
I think we will need unsafe API on Span to access T* |
Return |
@benaadams These are just wrappers over the existing methods. |
@jamesqo |
UPDATE (old 'obsolete' ask/suggestion deleted): |
@KrzysztofCwalina will kick off much broader public discussion around design and usage of |
Span may not really work well for some of these APIs because of the stack only nature of it (specifically the async APIs) |
@davidfowl but if I have some unmanged memory, I really want to just pass a span to it rather than cipu to managed array. It isn't allocated on the stack |
I'm going to close this in favor of dotnet/corefx#21281. @jamesqo, if anything would be covered by this issue that's not covered functionally by the other, please comment over there. Thanks! |
@stephentoub Let me try to convince you that the item you linked to and all the - very useful! - changes made to the .NET APIs WRT An example: am loading bytes from a Ultimately, everything works OK-ish except that Sample code: private static byte[] Decompress(byte[] data) {
using var output = new MemoryStream();
using var input = new MemoryStream(data);
using var gzip = new GZipStream(input, CompressionMode.Decompress);
zip.CopyTo(output);
output.Flush();
return output.ToArray();
} In practice, I don't need to write into this I could do things differently: the Exactly in the same way in the middle of the above method, instead of In both cases, I now have blocks of memory which logically represent a single contiguous array of bytes. I could create a single block and copy all the bytes, but that's just wasteful. Since most FX APIs still only work with I've looked almost everywhere, and have seen a few things which could help me, but not quite:
So... am I missing something? It seems to me that all that I need would be an implementation of Is there something in FX that I have missed? I'm sure I have, please advise 😊 Thanks for reading and thanks for the great work everyone is doing in .NET Core! |
@stephentoub Please disregard all references to |
I think a better solution would be to expose the innards of those Stream implementation as flat APIs (we've discussed this internally for a while now). public static class GZip
{
public OperationStatus TryDecompress(ReadOnlySpan<byte> input, Span<byte> output, out int bytesWritten);
} Something like the above, I haven't thought about it deeply though (it might need to be non static since zlib is stateful) |
Thanks. Almost all of the APIs proposed in this thread are addressed, in that they're all Write/Read methods that take |
@davidfowl Of course, having a more "modern" API would be much better than struggling with the aging @stephentoub Yes, after I wrote all that I stumbled upon dotnet/corefx#21380 which is much more fitting for what I'm trying to do here, in the absence of pervasive changes to the FX along the lines of @davidfowl proposal above. Sorry for not finding that other item sooner. In fact, when I think about it a bit more - the dotnet/corefx#22404 looks exactly like what I would expect to have one day - one stream to read values from and other to write into; in practice most of my memory streams are either read-only or write-only. I do share @KrzysztofCwalina sentiment though - how the hell are we supposed to name this thing? 😉I actually have a working implementation for portions of both items you linked to; I have some concerns which I will raise on there. Thank you both for your comments clearly made in your own time, over the WE, it's much appreciated! |
Background
To avoid unnecessary allocations, lots of code that works with Streams and I/O passes around a 'portion' of an array containing the relevant data instead of copying it to a new one. Since .NET does not yet support multiple return values, this is commonly represented as an
ArraySegment<T>
, where T is the type of the element contained in the array. Unfortunately, the System.IO namespace does not have overly sophisticated support forArraySegments
(aside from the recently-addedTryGetBuffer
forMemoryStream
), forcing people who use them to 'unravel' them like this:I propose adding convenience methods to the existing System.IO APIs that will make this less verbose, and prevent accidents like e.g. the programmer mixing up
Offset
andCount
.Proposed API
The text was updated successfully, but these errors were encountered: