I was trying to write some try catch
for Convert.FromBase64String()
and I found out that it already has TryFromBase64String()
method. But it needs 3 arguments:
public static bool TryFromBase64String(string s, Span<byte> bytes, out int bytesWritten);
So how can I use Span<byte> bytes
there?
I only found this in docs, but without proper description. Maybe this is too obvious.
https://learn.microsoft.com/en-us/dotnet/api/system.convert.tryfrombase64string?view=netcore-2.1
Thank to @Damien_The_Unbeliever and THIS article I found out more about Span
. So...
Span is used for saving memory and don't call GC so much. It can store arrays or portion of array, but I still can't figure out how to use it in that method.
As written in the linked questions, System.Span<T>
is a new C# 7.2 feature (and the Convert.TryFromBase64String
is a newer .NET Core feature)
To use System.Span<>
you have to install a nuget package:
Install-Package System.Memory
Then to use it:
byte[] buffer = new byte[((b64string.Length * 3) + 3) / 4 -
(b64string.Length > 0 && b64string[b64string.Length - 1] == '=' ?
b64string.Length > 1 && b64string[b64string.Length - 2] == '=' ?
2 : 1 : 0)];
int written;
bool success = Convert.TryFromBase64String(b64string, buffer, out written);
Where b64string
is your base-64 string. The over-complicated size for buffer
should be the exact length of the buffer based on the length of the b64string
.
You could use it like this, making use of all the TryFromBase64String
arguments:
public string DecodeUtf8Base64(string input)
{
var bytes = new Span<byte>(new byte[256]); // 256 is arbitrary
if (!Convert.TryFromBase64String(input, bytes, out var bytesWritten))
{
throw new InvalidOperationException("The input is not a valid base64 string");
}
return Encoding.UTF8.GetString(bytes.Slice(0, bytesWritten));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With