[c#] 最快的方法来转换一个可能null-terminated的ascii byte []到一个字符串?



3 Answers

Oneliner(假设缓冲区实际上包含一个格式化为空的字符串):

String MyString = Encoding.ASCII.GetString(MyByteBuffer).TrimEnd((Char)0);
Question

我需要将一个(可能)以空字符结尾的ascii字节数组转换为C#中的字符串,而且我发现这样做的最快方法是使用下面显示的UnsafeAsciiBytesToString方法。 此方法使用String.String(sbyte *)构造函数,其中包含警告:

“值参数被假定为指向表示使用默认ANSI代码页编码的字符串的数组(即Encoding.Default指定的编码方法)。

注意: 由于默认的ANSI代码页是依赖于系统的,因此由相同的有符号字节数组构造的字符串在不同的系统上可能会有所不同。 * ...

*如果指定的数组不是空终止的,这个构造函数的行为是依赖于系统的。 例如,这种情况可能会导致访问冲突。 *

现在,我确信字符串编码的方式永远不会改变...但我的应用程序运行在系统上的默认代码页可能会改变。 那么,有什么理由不应该为了这个目的而使用String.String(sbyte *)来运行尖叫吗?

using System;
using System.Text;

namespace FastAsciiBytesToString
{
    static class StringEx
    {
        public static string AsciiBytesToString(this byte[] buffer, int offset, int maxLength)
        {
            int maxIndex = offset + maxLength;

            for( int i = offset; i < maxIndex; i++ )
            {
                /// Skip non-nulls.
                if( buffer[i] != 0 ) continue;
                /// First null we find, return the string.
                return Encoding.ASCII.GetString(buffer, offset, i - offset);
            }
            /// Terminating null not found. Convert the entire section from offset to maxLength.
            return Encoding.ASCII.GetString(buffer, offset, maxLength);
        }

        public static string UnsafeAsciiBytesToString(this byte[] buffer, int offset)
        {
            string result = null;

            unsafe
            {
                fixed( byte* pAscii = &buffer[offset] )
                { 
                    result = new String((sbyte*)pAscii);
                }
            }

            return result;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            byte[] asciiBytes = new byte[]{ 0, 0, 0, (byte)'a', (byte)'b', (byte)'c', 0, 0, 0 };

            string result = asciiBytes.AsciiBytesToString(3, 6);

            Console.WriteLine("AsciiBytesToString Result: \"{0}\"", result);

            result = asciiBytes.UnsafeAsciiBytesToString(3);

            Console.WriteLine("UnsafeAsciiBytesToString Result: \"{0}\"", result);

            /// Non-null terminated test.
            asciiBytes = new byte[]{ 0, 0, 0, (byte)'a', (byte)'b', (byte)'c' };

            result = asciiBytes.UnsafeAsciiBytesToString(3);

            Console.WriteLine("UnsafeAsciiBytesToString Result: \"{0}\"", result);

            Console.ReadLine();
        }
    }
}



使用.NET类System.Text.Encoding将byte []对象转换为包含ASCII对等字符串(反之亦然)的字符串的简单/安全/快速的方法。 该类有一个静态函数返回一个ASCII编码器:

从字符串到字节[]:

string s = "Hello World!"
byte[] b = System.Text.Encoding.ASCII.GetBytes(s);

从字节[]到字符串:

byte[] byteArray = new byte[] {0x41, 0x42, 0x09, 0x00, 0x255};
string s = System.Text.Encoding.ASCII.GetString(byteArray);



s = s.Substring(0, s.IndexOf((char) 0));



考虑一种可能性:检查默认代码页是否可接受,并使用该信息在运行时选择转换机制。

这也可以考虑字符串是否实际上是以空字符结尾的,但是一旦你这样做了,当然速度就会消失。




Related