ReadOnlySequence <char>преобразование из ReadOnlySequence <byte>? - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь использовать System.IO.Pipelines для анализа больших текстовых файлов.

Но я не могу найти функцию преобразования из ReadOnlySequence в ReadOnlySequence. Например, как MemoryMarshal.Cast<byte,char>.

ИМХО, довольно бесполезно иметь обобщенный c ReadOnlySequence<T>, если применяется только один конкретный тип (байт).

    static async Task ReadPipeAsync(PipeReader reader, IStringValueFactory factory)
    {
      while (true)
      {
        ReadResult result = await reader.ReadAsync();

        ReadOnlySequence<byte> buffer = result.Buffer;

        //ReadOnlySequence<char> chars = buffer.CastTo<char>(); ???
       }
     }

1 Ответ

0 голосов
/ 29 января 2020

Вы должны написать оператор преобразования , чтобы выполнить этот бросок. Вы не можете разыграть это явно. Имейте в виду, что char [] составляет два байта, поэтому вам нужно выбрать алгоритм кодирования.

ИМХО, довольно бесполезно иметь обобщенный c ReadOnlySequence<T>, если есть только один конкретный тип (байт) применимо.

Хотя верно, что System.IO.Pipelines даст вам ReadOnlySequence<byte> только потому, что PipeReader присоединен к потоку, который является просто потоком байтов Существуют и другие варианты использования для ReadOnlySequence<T>, например,

ReadOnlySequence<char> roChars = new ReadOnlySequence<char>("some chars".ToCharArray());
ReadOnlySequence<string> roStrings = new ReadOnlySequence<string>(new string[] { "string1", "string2", "Another String" });

Ваш оператор преобразования будет иметь логин c, аналогичный приведенному ниже, но вы должны правильно настроить кодировку.

    static void Main(string[] args)
    {
        // create a 64k Readonly sequence of random bytes
        var ros = new ReadOnlySequence<byte>(GenerateRandomBytes(64000));

        //Optionally extract the section of the ReadOnlySequence we are interested in
        var mySlice = ros.Slice(22222, 55555);

        char[] charArray;

        // Check if the slice is a single segment - not really necessary
        // included for explanation only
        if(mySlice.IsSingleSegment)
        {
            charArray = Encoding.ASCII.GetString(mySlice.FirstSpan).ToCharArray();
        }
        else
        // Could only do this and always assume multiple spans
        // which is highly likley for a PipeReader stream
        {
            Span<byte> theSpan = new byte[ros.Length];
            mySlice.CopyTo(theSpan);
            // ASCII Encoding - one byte of span = 2 bytes of char
            charArray = Encoding.ASCII.GetString(theSpan).ToCharArray();
        }

        // Convert the char array back to a ReadOnlySegment<char>
        var rosChar = new ReadOnlySequence<char>(charArray);

    }

    public static byte[] GenerateRandomBytes(int length)
    {
        // Create a buffer
        byte[] randBytes;

        if (length >= 1)
            randBytes = new byte[length];
        else
            randBytes = new byte[1];

        // Create a new RNGCryptoServiceProvider.
        System.Security.Cryptography.RNGCryptoServiceProvider rand =
             new System.Security.Cryptography.RNGCryptoServiceProvider();

        // Fill the buffer with random bytes.
        rand.GetBytes(randBytes);

        // return the bytes.
        return randBytes;
    }
...