Usando C#, qual é o método mais eficiente de converter uma string contendo dados binários em um array de bytes

StackOverflow https://stackoverflow.com/questions/72176

  •  09-06-2019
  •  | 
  •  

Pergunta

Embora existam 100 maneiras de resolver o problema de conversão, estou me concentrando no desempenho.

Considerando que a string contém apenas dados binários, qual é o método mais rápido, em termos de desempenho, de converter esses dados em um byte[] (não char[]) em C#?

Esclarecimento:Estes não são dados ASCII, mas sim dados binários que estão em uma string.

Foi útil?

Solução

Não tenho certeza se ASCIIEncoding.GetBytes fará isso, porque ele suporta apenas o faixa 0x0000 a 0x007F.

Você diz que a string contém apenas bytes.Mas uma string .NET é uma matriz de caracteres e 1 caractere tem 2 bytes (porque um .NET armazena strings como UTF16).Então você pode ter duas situações para armazenar os bytes 0x42 e 0x98:

  1. A string era uma string ANSI e continha bytes e foi convertida em uma string unicode, portanto os bytes serão 0x00 0x42 0x00 0x98.(A string é armazenada como 0x0042 e 0x0098)
  2. A string era apenas uma matriz de bytes que você digitou ou acabou de receber em uma string e, portanto, tornou-se os seguintes bytes 0x42 0x98.(A string é armazenada como 0x9842)

Na primeira situação o resultado seria 0x42 e 0x3F (ascii para "B?").A segunda situação resultaria em 0x3F (ascii para "?").Isso é lógico, porque os caracteres estão fora do intervalo ASCII válido e o codificador não sabe o que fazer com esses valores.

Então, estou me perguntando por que é uma string com bytes?

  • Talvez contenha um byte codificado como uma string (por exemplo Base64)?
  • Talvez você deva começar com uma matriz de caracteres ou uma matriz de bytes?

Se você realmente tem a situação 2 e deseja obter os bytes dela, você deve usar o UnicodeEncoding.GetBytes chamar.Porque isso retornará 0x42 e 0x98.

Se você quiser passar de uma matriz de caracteres para uma matriz de bytes, o caminho mais rápido seria o Marshaling.Mas isso não é muito legal e usa memória dupla.

public Byte[] ConvertToBytes(Char[] source)
{
    Byte[] result = new Byte[source.Length * sizeof(Char)];
    IntPtr tempBuffer = Marshal.AllocHGlobal(result.Length);
    try
    {
        Marshal.Copy(source, 0, tempBuffer, source.Length);
        Marshal.Copy(tempBuffer, result, 0, result.Length);
    }
    finally
    {
        Marshal.FreeHGlobal(tempBuffer);
    }
    return result;
}

Outras dicas

não tem isso como uma string ASCII em C#!Cordas sempre contém UTF-16.Não perceber isso leva a muitos problemas.Dito isso, os métodos mencionados anteriormente funcionam porque consideram a string como codificada em UTF-16 e transformam os caracteres em símbolos ASCII.

/EDIT em resposta ao esclarecimento:como os dados binários entraram na string?Strings não devem conter dados binários (use byte[] por isso).

Se você quiser passar de uma string para dados binários, você deve saber qual codificação foi usada para converter os dados binários em uma string em primeiro lugar.Caso contrário, você poderá não obter os dados binários corretos.Portanto, a maneira mais eficiente é provavelmente GetBytes() em uma subclasse Encoding (como UTF8Encoding), mas você deve saber com certeza qual codificação.

O comentário de Kent Boogaart sobre a pergunta original resume muito bem.;]

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top