首页 > 解决方案 > 只读序列从 ReadOnlySequence 转换?

问题描述

我正在尝试使用 System.IO.Pipelines 来解析大型文本文件。

但是我找不到从 ReadOnlySequence 到 ReadOnlySequence 的转换函数。例如像MemoryMarshal.Cast<byte,char>.

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>(); ???
       }
     }

标签: system.io.pipelines

解决方案


您必须编写一个转换运算符来实现这种转换。你不能明确地转换它。请注意 char[] 是两个字节,因此您需要选择编码算法。

ReadOnlySequence<T>恕我直言,如果只有一种特定类型(字节)适用,那么拥有泛型是毫无用处的。

虽然确实System.IO.Pipelines只会给你 aReadOnlySequence<byte>因为 aPipeReader附加到只是一个字节流的 Stream ,但还有其他用例 aReadOnlySequence<T>例如,

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

您的转换运算符将具有与以下类似的逻辑,但您将适当地设置您的编码。

    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;
    }

推荐阅读