Codificação de caracteres no .NETCharacter Encoding in .NET

Os caracteres são entidades abstratas que podem ser representadas de muitas maneiras diferentes.Characters are abstract entities that can be represented in many different ways. Uma codificação de caracteres é um sistema que emparelha cada caractere em um conjunto de caracteres com suporte com algum valor que representa esse caractere.A character encoding is a system that pairs each character in a supported character set with some value that represents that character. Por exemplo, o código Morse é uma codificação de caracteres que emparelha cada caractere do alfabeto romano com um padrão de pontos e traços adequados para transmissão por linhas telegráficas.For example, Morse code is a character encoding that pairs each character in the Roman alphabet with a pattern of dots and dashes that are suitable for transmission over telegraph lines. Uma codificação de caracteres para computadores emparelha cada caractere em um conjunto de caracteres com suporte com um valor numérico que representa esse caractere.A character encoding for computers pairs each character in a supported character set with a numeric value that represents that character. Uma codificação de caracteres tem dois componentes distintos:A character encoding has two distinct components:

  • Um codificador, que converte uma sequência de caracteres em uma sequência de valores numéricos (bytes).An encoder, which translates a sequence of characters into a sequence of numeric values (bytes).

  • Um decodificador, que converte uma sequência de bytes em uma sequência de caracteres.A decoder, which translates a sequence of bytes into a sequence of characters.

A codificação de caracteres descreve as regras por meio das quais um codificador e um decodificador são operados.Character encoding describes the rules by which an encoder and a decoder operate. Por exemplo, a classe UTF8Encoding descreve as regras de codificação para UTF-8 (Formato de Transformação Unicode de 8 bits), e de decodificação desse formato, que usa de um a quatro bytes para representar um único caractere Unicode.For example, the UTF8Encoding class describes the rules for encoding to, and decoding from, 8-bit Unicode Transformation Format (UTF-8), which uses one to four bytes to represent a single Unicode character. Codificar e decodificar também podem incluir a validação.Encoding and decoding can also include validation. Por exemplo, a classe UnicodeEncoding verifica todos os substitutos para certificar-se de eles constituem pares alternativos válidos.For example, the UnicodeEncoding class checks all surrogates to make sure they constitute valid surrogate pairs. (Um par alternativo consiste em um caractere com um ponto de código que varia de U + D800 para U + DBFF seguido por um caractere com um ponto de código que varia de U + DC00 para U + DFFF.) Uma estratégia de fallback determina como um codificador trata caracteres inválidos ou como um decodificador manipula bytes inválidos.(A surrogate pair consists of a character with a code point that ranges from U+D800 to U+DBFF followed by a character with a code point that ranges from U+DC00 to U+DFFF.) A fallback strategy determines how an encoder handles invalid characters or how a decoder handles invalid bytes.

Aviso

As classes de codificação .NET fornecem uma maneira de armazenar e converter dados de caractere..NET encoding classes provide a way to store and convert character data. Elas não devem ser usadas para armazenar dados binários no formato de cadeia de caracteres.They should not be used to store binary data in string form. Dependendo da codificação usada, a conversão de dados binários em formato de cadeia de caracteres com classes de codificação pode introduzir um comportamento inesperado e produzir dados imprecisos ou corrompidos.Depending on the encoding used, converting binary data to string format with the encoding classes can introduce unexpected behavior and produce inaccurate or corrupted data. Para converter dados binários em um formulário de cadeia de caracteres, use o método Convert.ToBase64String.To convert binary data to a string form, use the Convert.ToBase64String method.

O .NET usa a codificação UTF-16 (representado pela classe UnicodeEncoding) para representar caracteres e cadeias de caracteres..NET uses the UTF-16 encoding (represented by the UnicodeEncoding class) to represent characters and strings. Aplicativos que segmentam o Common Language Runtime e usam codificadores para mapear representações de caracteres Unicode com suporte pelo common language runtime para outros esquemas de codificação.Applications that target the common language runtime use encoders to map Unicode character representations supported by the common language runtime to other encoding schemes. Eles usam decodificadores para mapear caracteres de codificações não Unicode para Unicode.They use decoders to map characters from non-Unicode encodings to Unicode.

Este tópico é composto pelas seguintes seções:This topic consists of the following sections:

Codificações no .NETEncodings in .NET

Todas as classes de codificação de caracteres no .NET são herdadas da classe System.Text.Encoding, uma classe abstrata que define a funcionalidade comum a todas as codificações de caracteres.All character encoding classes in .NET inherit from the System.Text.Encoding class, which is an abstract class that defines the functionality common to all character encodings. Para acessar os objetos de codificação individuais implementados no .NET, faça o seguinte:To access the individual encoding objects implemented in .NET, do the following:

  • Usar propriedades estáticas da classe Encoding, que retornam objetos que representam as codificações de caracteres padrão disponíveis no .NET (ASCII, UTF-7, UTF-8, UTF-16 e UTF-32).Use the static properties of the Encoding class, which return objects that represent the standard character encodings available in .NET (ASCII, UTF-7, UTF-8, UTF-16, and UTF-32). Por exemplo, a propriedade Encoding.Unicode retorna um objeto UnicodeEncoding.For example, the Encoding.Unicode property returns a UnicodeEncoding object. Cada objeto usa o fallback de substituição para lidar com cadeias de caracteres que ele não consegue codificar e bytes que ele não consegue decodificar.Each object uses replacement fallback to handle strings that it cannot encode and bytes that it cannot decode. (Para obter mais informações, consulte a seção Replacement Fallback (Fallback de substituição).)(For more information, see the Replacement Fallback section.)

  • Chame o construtor de classe da codificação.Call the encoding's class constructor. A instância de objetos para as codificações ASCII, UTF-7, UTF-8, UTF-16 e UTF-32 podem ser criadas dessa forma.Objects for the ASCII, UTF-7, UTF-8, UTF-16, and UTF-32 encodings can be instantiated in this way. Por padrão, cada objeto usa fallback de substituição para manipular as cadeias de caracteres que ele não consegue codificar e bytes que ele não consegue decodificar, mas, em vez disso, você pode especificar que uma exceção seja gerada.By default, each object uses replacement fallback to handle strings that it cannot encode and bytes that it cannot decode, but you can specify that an exception should be thrown instead. (Para obter mais informações, consulte as seções Fallback de substituição e Fallback de exceção.)(For more information, see the Replacement Fallback and Exception Fallback sections.)

  • Chame o construtor Encoding.Encoding(Int32) e passe por ele um inteiro que represente a codificação.Call the Encoding.Encoding(Int32) constructor and pass it an integer that represents the encoding. Os objetos de codificação padrão usam o fallback de substituição e a página de código e o DBCS (conjunto de caracteres de dois bytes) que codificam objetos usam o fallback que melhor se ajusta para manipular cadeias de caracteres que eles não conseguem codificar e bytes que eles não conseguem decodificar.Standard encoding objects use replacement fallback, and code page and double-byte character set (DBCS) encoding objects use best-fit fallback to handle strings that they cannot encode and bytes that they cannot decode. (Para obter mais informações, consulte a seção Best-Fit Fallback (Fallback de melhor ajuste).)(For more information, see the Best-Fit Fallback section.)

  • Chame o método Encoding.GetEncoding, que retorna qualquer padrão, página de código ou codificação DBCS disponível no .NET.Call the Encoding.GetEncoding method, which returns any standard, code page, or DBCS encoding available in .NET. As sobrecargas permitem especificar um objeto de fallback para o codificador e o decodificador.Overloads let you specify a fallback object for both the encoder and the decoder.

Observação

O padrão Unicode atribui um ponto de código (um número) e um nome a cada caractere em todos os scripts com suporte.The Unicode Standard assigns a code point (a number) and a name to each character in every supported script. Por exemplo, o caractere "A" é representado pelo ponto de código de U+0041 e o nome "LETRA MAIÚSCULA LATINA A".For example, the character "A" is represented by the code point U+0041 and the name "LATIN CAPITAL LETTER A". As codificações UTF (Unicode Transformation Format) definem maneiras de codificar esse ponto de código em uma sequência de um ou mais bytes.The Unicode Transformation Format (UTF) encodings define ways to encode that code point into a sequence of one or more bytes. Um esquema de codificação Unicode simplifica o desenvolvimento de aplicativos prontos para o mundo, porque ele permite que qualquer conjunto de caracteres sejam representados em uma única codificação.A Unicode encoding scheme simplifies world-ready application development because it allows characters from any character set to be represented in a single encoding. Os desenvolvedores de aplicativos não precisam mais controlar o esquema de codificação usado para gerar caracteres para um idioma específico ou sistema de gravação e os dados podem ser compartilhados entre sistemas internacionalmente sem serem corrompidos.Application developers no longer have to keep track of the encoding scheme that was used to produce characters for a specific language or writing system, and data can be shared among systems internationally without being corrupted.

O .NET dá suporte a três codificações definidas pelo padrão Unicode: UTF-8, UTF-16 e UTF-32..NET supports three encodings defined by the Unicode standard: UTF-8, UTF-16, and UTF-32. Para obter mais informações, consulte Padrão Unicode na página inicial do Unicode.For more information, see The Unicode Standard at the Unicode home page.

Você pode recuperar informações sobre todas as codificações disponíveis no .NET chamando o método Encoding.GetEncodings.You can retrieve information about all the encodings available in .NET by calling the Encoding.GetEncodings method. O .NET dá suporte aos sistemas de codificação de caracteres listados na tabela a seguir..NET supports the character encoding systems listed in the following table.

EncodingEncoding ClasseClass DescriçãoDescription Vantagens/desvantagensAdvantages/disadvantages
ASCIIASCII ASCIIEncoding Codifica um intervalo limitado de caracteres usando os menores sete bits de um byte.Encodes a limited range of characters by using the lower seven bits of a byte. Como essa codificação só dá suporte a valores de caracteres de U+0000 a U+007F, na maioria dos casos, ela é inadequada para aplicativos internacionalizados.Because this encoding only supports character values from U+0000 through U+007F, in most cases it is inadequate for internationalized applications.
UTF-7UTF-7 UTF7Encoding Representa caracteres como sequências de caracteres ASCII de 7 bits.Represents characters as sequences of 7-bit ASCII characters. Caracteres Unicode não ASCII são representados por uma sequência de escape de caracteres ASCII.Non-ASCII Unicode characters are represented by an escape sequence of ASCII characters. O UTF-7 dá suporte a protocolos como os de email e de grupos de notícias.UTF-7 supports protocols such as email and newsgroup protocols. No entanto, o UTF-7 não é particularmente seguro ou robusto.However, UTF-7 is not particularly secure or robust. Em alguns casos, alterar um bit pode alterar radicalmente a interpretação de toda uma cadeia de caracteres UTF-7.In some cases, changing one bit can radically alter the interpretation of an entire UTF-7 string. Em outros casos, diferentes cadeias de caracteres UTF-7 podem codificar o mesmo texto.In other cases, different UTF-7 strings can encode the same text. Para as sequências que incluem caracteres não ASCII, o UTF-7 requer mais espaço do que o UTF-8 e a codificação/decodificação é mais lenta.For sequences that include non-ASCII characters, UTF-7 requires more space than UTF-8, and encoding/decoding is slower. Consequentemente, você deve usar o UTF-8 em vez do UTF-7, se possível.Consequently, you should use UTF-8 instead of UTF-7 if possible.
UTF-8UTF-8 UTF8Encoding Representa cada ponto de código Unicode como uma sequência de um a quatro bytes.Represents each Unicode code point as a sequence of one to four bytes. O UTF-8 dá suporte a tamanhos de dados de 8 bits e funciona bem com muitos sistemas operacionais existentes.UTF-8 supports 8-bit data sizes and works well with many existing operating systems. Para o intervalo de caracteres ASCII, o UTF-8 é idêntico à codificação ASCII e permite um conjunto mais amplo de caracteres.For the ASCII range of characters, UTF-8 is identical to ASCII encoding and allows a broader set of characters. No entanto, para scripts CJK (chinês-japonês-coreano), o UTF-8 pode exigir três bytes para cada caractere e pode eventualmente gerar tamanhos de dados maiores do que o UTF-16.However, for Chinese-Japanese-Korean (CJK) scripts, UTF-8 can require three bytes for each character, and can potentially cause larger data sizes than UTF-16. Observe que, às vezes, a quantidade de dados ASCII, como tags HTML, justifica o tamanho maior do intervalo CJK.Note that sometimes the amount of ASCII data, such as HTML tags, justifies the increased size for the CJK range.
UTF-16UTF-16 UnicodeEncoding Representa cada ponto de código Unicode como uma sequência de um a dois inteiros de 16 bits.Represents each Unicode code point as a sequence of one or two 16-bit integers. Os caracteres Unicode mais comuns exigem apenas um ponto de código UTF-16, embora os caracteres suplementares Unicode (U+10000 e maiores) exigem dois pontos de código UTF-16 alternativos.Most common Unicode characters require only one UTF-16 code point, although Unicode supplementary characters (U+10000 and greater) require two UTF-16 surrogate code points. Há suporte para as ordens de byte little endian e big endian.Both little-endian and big-endian byte orders are supported. A codificação UTF-16 é usada pelo Common Language Runtime para representar os valores Char e String, e é usada pelo sistema operacional Windows para representar valores WCHAR.UTF-16 encoding is used by the common language runtime to represent Char and String values, and it is used by the Windows operating system to represent WCHAR values.
UTF-32UTF-32 UTF32Encoding Representa cada ponto de código Unicode como um inteiro de 32 bits.Represents each Unicode code point as a 32-bit integer. Há suporte para as ordens de byte little endian e big endian.Both little-endian and big-endian byte orders are supported. A codificação UTF-32 é usada quando aplicativos desejam evitar o comportamento do ponto de código alternativo de codificação UTF-16 em sistemas operacionais para os quais o espaço codificado é muito importante.UTF-32 encoding is used when applications want to avoid the surrogate code point behavior of UTF-16 encoding on operating systems for which encoded space is too important. Glifos únicos renderizados em uma tela ainda podem ser codificados com mais de um caractere UTF-32.Single glyphs rendered on a display can still be encoded with more than one UTF-32 character.
Codificações ANSI/ISOANSI/ISO encodings Fornece suporte a uma variedade de páginas de código.Provides support for a variety of code pages. Em sistemas operacionais Windows, páginas de código são usadas para oferecer suporte a um idioma específico ou a um grupo de idiomas.On Windows operating systems, code pages are used to support a specific language or group of languages. Para uma tabela que lista as páginas de código com suporte pelo .NET, confira a classe Encoding.For a table that lists the code pages supported by .NET, see the Encoding class. Você pode recuperar um objeto de codificação para uma página de código específico chamando o método Encoding.GetEncoding(Int32).You can retrieve an encoding object for a particular code page by calling the Encoding.GetEncoding(Int32) method. Uma página de código contém 256 pontos de código e é baseada em zero.A code page contains 256 code points and is zero-based. Na maioria das páginas de código, os pontos de código de 0 a 127 representam o conjunto de caracteres ASCII e pontos de código de 128 a 255 diferem significativamente entre páginas de código.In most code pages, code points 0 through 127 represent the ASCII character set, and code points 128 through 255 differ significantly between code pages. Por exemplo, a página de código 1252 fornece os caracteres para sistemas com alfabeto latino, incluindo inglês, alemão e francês.For example, code page 1252 provides the characters for Latin writing systems, including English, German, and French. Os últimos 128 pontos de código na página de código 1252 contêm os caracteres de acentuação.The last 128 code points in code page 1252 contain the accent characters. A página de código 1253 fornece códigos de caracteres que são necessários no sistema alfabético grego.Code page 1253 provides character codes that are required in the Greek writing system. Os últimos 128 pontos de código na página de código 1253 contêm os caracteres gregos.The last 128 code points in code page 1253 contain the Greek characters. Como resultado, um aplicativo que se baseia em páginas de código ANSI não pode armazenar grego e alemão no mesmo fluxo de texto, a menos que inclua um identificador que indique a página de código referenciada.As a result, an application that relies on ANSI code pages cannot store Greek and German in the same text stream unless it includes an identifier that indicates the referenced code page.
Codificações de conjunto de caracteres de byte duplo (DBCS)Double-byte character set (DBCS) encodings Oferece suporte a idiomas, como chinês, japonês e coreano, que contêm mais de 256 caracteres.Supports languages, such as Chinese, Japanese, and Korean, that contain more than 256 characters. Um DBCS, um par de pontos de código (de byte duplo) representa cada caractere.In a DBCS, a pair of code points (a double byte) represents each character. A propriedade Encoding.IsSingleByte retorna false para codificações DBCS.The Encoding.IsSingleByte property returns false for DBCS encodings. Você pode recuperar um objeto de codificação para determinado DBCS chamando o método Encoding.GetEncoding(Int32).You can retrieve an encoding object for a particular DBCS by calling the Encoding.GetEncoding(Int32) method. Um DBCS, um par de pontos de código (de byte duplo) representa cada caractere.In a DBCS, a pair of code points (a double byte) represents each character. Quando um aplicativo manipula dados DBCS, o primeiro byte de um caractere DBCS (o byte inicial) é processado em combinação com o byte final que vem imediatamente a seguir.When an application handles DBCS data, the first byte of a DBCS character (the lead byte) is processed in combination with the trail byte that immediately follows it. Como um único par de pontos de código de byte duplo pode representar caracteres diferentes dependendo da página de código, esse esquema ainda não permite a combinação dos dois idiomas, como japonês e chinês no mesmo fluxo de dados.Because a single pair of double-byte code points can represent different characters depending on the code page, this scheme still does not allow for the combination of two languages, such as Japanese and Chinese, in the same data stream.

Essas codificações permitem que você trabalhe com caracteres Unicode, bem como com codificações mais comumente usadas em aplicativos herdados.These encodings enable you to work with Unicode characters as well as with encodings that are most commonly used in legacy applications. Além disso, você pode criar uma codificação personalizada definindo uma classe que deriva de Encoding e substituindo seus membros.In addition, you can create a custom encoding by defining a class that derives from Encoding and overriding its members.

Notas de plataforma: .Net CorePlatform Notes: .NET Core

Por padrão, o .NET Core não disponibiliza nenhuma codificação de página de código diferente de página de código 28591 e das codificações Unicode, como UTF-8 e UTF-16.By default, .NET Core does not make available any code page encodings other than code page 28591 and the Unicode encodings, such as UTF-8 and UTF-16. No entanto, você pode adicionar as codificações de página de código encontradas em aplicativos do Windows padrão que direcionam o .NET ao seu aplicativo.However, you can add the code page encodings found in standard Windows apps that target .NET to your app. Para saber mais, confira o tópico CodePagesEncodingProvider.For complete information, see the CodePagesEncodingProvider topic.

Selecionando uma classe de codificaçãoSelecting an Encoding Class

Se você tiver a oportunidade de escolher a codificação a ser usada pelo seu aplicativo, você deverá usar a codificação Unicode, preferencialmente UTF8Encoding ou UnicodeEncoding.If you have the opportunity to choose the encoding to be used by your application, you should use a Unicode encoding, preferably either UTF8Encoding or UnicodeEncoding. (O .NET também dá suporte a uma terceira codificação Unicode, UTF32Encoding.)(.NET also supports a third Unicode encoding, UTF32Encoding.)

Se você estiver planejando usar uma codificação ASCII (ASCIIEncoding), escolha UTF8Encoding em vez disso.If you are planning to use an ASCII encoding (ASCIIEncoding), choose UTF8Encoding instead. As duas codificações são idênticas para o conjunto de caracteres ASCII, mas o UTF8Encoding tem as seguintes vantagens:The two encodings are identical for the ASCII character set, but UTF8Encoding has the following advantages:

  • Ele pode representar todos os caracteres Unicode, enquanto o ASCIIEncoding dá suporte apenas aos valores de caracteres Unicode entre U+0000 e U+007F.It can represent every Unicode character, whereas ASCIIEncoding supports only the Unicode character values between U+0000 and U+007F.

  • Ele fornece detecção de erros e melhor segurança.It provides error detection and better security.

  • Ele foi ajustado para ser o mais rápido possível e deve ser mais rápido do que qualquer outra codificação.It has been tuned to be as fast as possible and should be faster than any other encoding. Mesmo para o conteúdo totalmente ASCII, as operações executadas com o UTF8Encoding são mais rápidas que as operações executadas com o ASCIIEncoding.Even for content that is entirely ASCII, operations performed with UTF8Encoding are faster than operations performed with ASCIIEncoding.

Você deve considerar usar o ASCIIEncoding apenas para aplicativos herdados.You should consider using ASCIIEncoding only for legacy applications. No entanto, mesmo para aplicativos herdados, o UTF8Encoding pode ser uma escolha melhor pelos seguintes motivos (supondo as configurações padrão):However, even for legacy applications, UTF8Encoding might be a better choice for the following reasons (assuming default settings):

  • Se seu aplicativo tiver conteúdo que não é estritamente ASCII e codificá-lo com o ASCIIEncoding, cada caractere não ASCII codificará como um ponto de interrogação (?).If your application has content that is not strictly ASCII and encodes it with ASCIIEncoding, each non-ASCII character encodes as a question mark (?). Se o aplicativo decodificar esses dados, as informações serão perdidas.If the application then decodes this data, the information is lost.

  • Se seu aplicativo tiver conteúdo que não é estritamente ASCII e codificá-lo com o UTF8Encoding, o resultado parecerá ininteligível se interpretado como ASCII.If your application has content that is not strictly ASCII and encodes it with UTF8Encoding, the result seems unintelligible if interpreted as ASCII. No entanto, se o aplicativo usar um decodificador de UTF-8 para decodificar esses dados, os dados executarão uma viagem de ida e volta com êxito.However, if the application then uses a UTF-8 decoder to decode this data, the data performs a round trip successfully.

Em um aplicativo Web, os caracteres enviados ao cliente em resposta a uma solicitação da Web devem refletir a codificação usada no cliente.In a web application, characters sent to the client in response to a web request should reflect the encoding used on the client. Na maioria dos casos, você deve definir a propriedade HttpResponse.ContentEncoding com o valor retornado pela propriedade HttpRequest.ContentEncoding para exibir o texto na codificação que o usuário espera.In most cases, you should set the HttpResponse.ContentEncoding property to the value returned by the HttpRequest.ContentEncoding property to display text in the encoding that the user expects.

Usando um objeto de codificaçãoUsing an Encoding Object

Um codificador converte uma cadeia de caracteres (mais comumente, caracteres Unicode) em seu equivalente numérico (byte).An encoder converts a string of characters (most commonly, Unicode characters) to its numeric (byte) equivalent. Por exemplo, você pode usar um codificador ASCII para converter caracteres Unicode em ASCII para que eles possam ser exibidos no console.For example, you might use an ASCII encoder to convert Unicode characters to ASCII so that they can be displayed at the console. Para executar a conversão, você deve chamar o método Encoding.GetBytes.To perform the conversion, you call the Encoding.GetBytes method. Se você desejar determinar quantos bytes são necessários para armazenar os caracteres codificados antes de executar a codificação, você poderá chamar o método GetByteCount.If you want to determine how many bytes are needed to store the encoded characters before performing the encoding, you can call the GetByteCount method.

O exemplo a seguir usa uma matriz de byte único para codificar cadeias de caracteres em duas operações separadas.The following example uses a single byte array to encode strings in two separate operations. Ela mantém um índice que indica a posição inicial na matriz de bytes para o próximo conjunto de bytes codificados em ASCII.It maintains an index that indicates the starting position in the byte array for the next set of ASCII-encoded bytes. Ela chama o método ASCIIEncoding.GetByteCount(String) para garantir que a matriz de bytes seja grande o suficiente para acomodar a cadeia de caracteres codificada.It calls the ASCIIEncoding.GetByteCount(String) method to ensure that the byte array is large enough to accommodate the encoded string. Depois, chama o método ASCIIEncoding.GetBytes(String, Int32, Int32, Byte[], Int32) para codificar os caracteres na cadeia de caracteres.It then calls the ASCIIEncoding.GetBytes(String, Int32, Int32, Byte[], Int32) method to encode the characters in the string.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      string[] strings= { "This is the first sentence. ", 
                          "This is the second sentence. " };
      Encoding asciiEncoding = Encoding.ASCII;
      
      // Create array of adequate size.
      byte[] bytes = new byte[49];
      // Create index for current position of array.
      int index = 0;
      
      Console.WriteLine("Strings to encode:");
      foreach (var stringValue in strings) {
         Console.WriteLine("   {0}", stringValue);
         
         int count = asciiEncoding.GetByteCount(stringValue);
         if (count + index >=  bytes.Length)
            Array.Resize(ref bytes, bytes.Length + 50);

         int written = asciiEncoding.GetBytes(stringValue, 0, 
                                              stringValue.Length, 
                                              bytes, index);    
    
         index = index + written; 
      } 
      Console.WriteLine("\nEncoded bytes:");
      Console.WriteLine("{0}", ShowByteValues(bytes, index));
      Console.WriteLine();
      
      // Decode Unicode byte array to a string.
      string newString = asciiEncoding.GetString(bytes, 0, index);
      Console.WriteLine("Decoded: {0}", newString);
   }
   
   private static string ShowByteValues(byte[] bytes, int last ) 
   {
      string returnString = "   ";
      for (int ctr = 0; ctr <= last - 1; ctr++) {
         if (ctr % 20 == 0)
            returnString += "\n   ";
         returnString += String.Format("{0:X2} ", bytes[ctr]);
      }
      return returnString;
   }
}
// The example displays the following output:
//       Strings to encode:
//          This is the first sentence.
//          This is the second sentence.
//       
//       Encoded bytes:
//       
//          54 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 73 65
//          6E 74 65 6E 63 65 2E 20 54 68 69 73 20 69 73 20 74 68 65 20
//          73 65 63 6F 6E 64 20 73 65 6E 74 65 6E 63 65 2E 20
//       
//       Decoded: This is the first sentence. This is the second sentence.
Imports System.Text

Module Example
   Public Sub Main()
      Dim strings() As String = { "This is the first sentence. ", 
                                  "This is the second sentence. " }
      Dim asciiEncoding As Encoding = Encoding.ASCII
      
      ' Create array of adequate size.
      Dim bytes(50) As Byte
      ' Create index for current position of array.
      Dim index As Integer = 0
      
      Console.WriteLine("Strings to encode:")
      For Each stringValue In strings
         Console.WriteLine("   {0}", stringValue)
         
         Dim count As Integer = asciiEncoding.GetByteCount(stringValue)
         If count + index >=  bytes.Length Then
            Array.Resize(bytes, bytes.Length + 50)
         End If
         Dim written As Integer = asciiEncoding.GetBytes(stringValue, 0, 
                                                         stringValue.Length, 
                                                         bytes, index)    
    
         index = index + written 
      Next 
      Console.WriteLine()
      Console.WriteLine("Encoded bytes:")
      Console.WriteLine("{0}", ShowByteValues(bytes, index))
      Console.WriteLine()
      
      ' Decode Unicode byte array to a string.
      Dim newString As String = asciiEncoding.GetString(bytes, 0, index)
      Console.WriteLine("Decoded: {0}", newString)
   End Sub
   
   Private Function ShowByteValues(bytes As Byte(), last As Integer) As String
      Dim returnString As String = "   "
      For ctr As Integer = 0 To last - 1
         If ctr Mod 20 = 0 Then returnString += vbCrLf + "   "
         returnString += String.Format("{0:X2} ", bytes(ctr))
      Next
      Return returnString
   End Function
End Module
' The example displays the following output:
'       Strings to encode:
'          This is the first sentence.
'          This is the second sentence.
'       
'       Encoded bytes:
'       
'          54 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 73 65
'          6E 74 65 6E 63 65 2E 20 54 68 69 73 20 69 73 20 74 68 65 20
'          73 65 63 6F 6E 64 20 73 65 6E 74 65 6E 63 65 2E 20
'       
'       Decoded: This is the first sentence. This is the second sentence.

Um decodificador converte uma matriz de bytes que reflete uma codificação de caracteres específica em um conjunto de caracteres, seja em uma matriz de caracteres ou em uma cadeia de caracteres.A decoder converts a byte array that reflects a particular character encoding into a set of characters, either in a character array or in a string. Para decodificar uma matriz de bytes em uma matriz de caracteres, chame o método Encoding.GetChars.To decode a byte array into a character array, you call the Encoding.GetChars method. Para decodificar uma matriz de bytes em uma cadeia de caracteres, chame o método GetString.To decode a byte array into a string, you call the GetString method. Se você desejar determinar quantos caracteres são necessários para armazenar os bytes decodificados antes de executar a decodificação, você poderá chamar o método GetCharCount.If you want to determine how many characters are needed to store the decoded bytes before performing the decoding, you can call the GetCharCount method.

O exemplo a seguir codifica três cadeias de caracteres e, em seguida, as decodifica em uma única matriz de caracteres.The following example encodes three strings and then decodes them into a single array of characters. Ela mantém um índice que indica a posição inicial na matriz de bytes para o próximo conjunto de caracteres codificados.It maintains an index that indicates the starting position in the character array for the next set of decoded characters. Ela chama o método GetCharCount para garantir que a matriz de caracteres seja grande o suficiente para acomodar todos os caracteres decodificados.It calls the GetCharCount method to ensure that the character array is large enough to accommodate all the decoded characters. Depois, chama o método ASCIIEncoding.GetChars(Byte[], Int32, Int32, Char[], Int32) para decodificar a matriz de bytes.It then calls the ASCIIEncoding.GetChars(Byte[], Int32, Int32, Char[], Int32) method to decode the byte array.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      string[] strings = { "This is the first sentence. ", 
                           "This is the second sentence. ",
                           "This is the third sentence. " };
      Encoding asciiEncoding = Encoding.ASCII;
      // Array to hold encoded bytes.
      byte[] bytes;
      // Array to hold decoded characters.
      char[] chars = new char[50];
      // Create index for current position of character array.
      int index = 0;     
      
      foreach (var stringValue in strings) {
         Console.WriteLine("String to Encode: {0}", stringValue);
         // Encode the string to a byte array.
         bytes = asciiEncoding.GetBytes(stringValue);
         // Display the encoded bytes.
         Console.Write("Encoded bytes: ");
         for (int ctr = 0; ctr < bytes.Length; ctr++)
            Console.Write(" {0}{1:X2}", 
                          ctr % 20 == 0 ? Environment.NewLine : "", 
                          bytes[ctr]);
         Console.WriteLine();

         // Decode the bytes to a single character array.
         int count = asciiEncoding.GetCharCount(bytes);
         if (count + index >=  chars.Length)
            Array.Resize(ref chars, chars.Length + 50);

         int written = asciiEncoding.GetChars(bytes, 0, 
                                              bytes.Length, 
                                              chars, index);              
         index = index + written;
         Console.WriteLine();       
      }
      
      // Instantiate a single string containing the characters.
      string decodedString = new string(chars, 0, index - 1);
      Console.WriteLine("Decoded string: ");
      Console.WriteLine(decodedString);
   }
}
// The example displays the following output:
//    String to Encode: This is the first sentence.
//    Encoded bytes:
//    54 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 73 65
//    6E 74 65 6E 63 65 2E 20
//    
//    String to Encode: This is the second sentence.
//    Encoded bytes:
//    54 68 69 73 20 69 73 20 74 68 65 20 73 65 63 6F 6E 64 20 73
//    65 6E 74 65 6E 63 65 2E 20
//    
//    String to Encode: This is the third sentence.
//    Encoded bytes:
//    54 68 69 73 20 69 73 20 74 68 65 20 74 68 69 72 64 20 73 65
//    6E 74 65 6E 63 65 2E 20
//    
//    Decoded string:
//    This is the first sentence. This is the second sentence. This is the third sentence.
Imports System.Text

Module Example
   Public Sub Main()
      Dim strings() As String = { "This is the first sentence. ", 
                                  "This is the second sentence. ",
                                  "This is the third sentence. " }
      Dim asciiEncoding As Encoding = Encoding.ASCII
      ' Array to hold encoded bytes.
      Dim bytes() As Byte
      ' Array to hold decoded characters.
      Dim chars(50) As Char
      ' Create index for current position of character array.
      Dim index As Integer     
      
      For Each stringValue In strings
         Console.WriteLine("String to Encode: {0}", stringValue)
         ' Encode the string to a byte array.
         bytes = asciiEncoding.GetBytes(stringValue)
         ' Display the encoded bytes.
         Console.Write("Encoded bytes: ")
         For ctr As Integer = 0 To bytes.Length - 1
            Console.Write(" {0}{1:X2}", If(ctr Mod 20 = 0, vbCrLf, ""), 
                                        bytes(ctr))
         Next         
         Console.WriteLine()

         ' Decode the bytes to a single character array.
         Dim count As Integer = asciiEncoding.GetCharCount(bytes)
         If count + index >=  chars.Length Then
            Array.Resize(chars, chars.Length + 50)
         End If
         Dim written As Integer = asciiEncoding.GetChars(bytes, 0, 
                                                         bytes.Length, 
                                                         chars, index)              
         index = index + written
         Console.WriteLine()       
      Next
      
      ' Instantiate a single string containing the characters.
      Dim decodedString As New String(chars, 0, index - 1)
      Console.WriteLine("Decoded string: ")
      Console.WriteLine(decodedString)
   End Sub
End Module
' The example displays the following output:
'    String to Encode: This is the first sentence.
'    Encoded bytes:
'    54 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 73 65
'    6E 74 65 6E 63 65 2E 20
'    
'    String to Encode: This is the second sentence.
'    Encoded bytes:
'    54 68 69 73 20 69 73 20 74 68 65 20 73 65 63 6F 6E 64 20 73
'    65 6E 74 65 6E 63 65 2E 20
'    
'    String to Encode: This is the third sentence.
'    Encoded bytes:
'    54 68 69 73 20 69 73 20 74 68 65 20 74 68 69 72 64 20 73 65
'    6E 74 65 6E 63 65 2E 20
'    
'    Decoded string:
'    This is the first sentence. This is the second sentence. This is the third sentence.

Os métodos de codificação e decodificação de uma classe derivada de Encoding foram criados para funcionar em um conjunto completo de dados; ou seja, todos os dados a serem codificados ou decodificados são fornecido em uma única chamada de método.The encoding and decoding methods of a class derived from Encoding are designed to work on a complete set of data; that is, all the data to be encoded or decoded is supplied in a single method call. No entanto, em alguns casos, os dados estão disponíveis em um fluxo e os dados a serem codificados ou decodificados podem estar disponíveis somente em operações de leitura separadas.However, in some cases, data is available in a stream, and the data to be encoded or decoded may be available only from separate read operations. Isso requer a operação de codificação ou decodificação para lembrar qualquer estado salvo em sua invocação anterior.This requires the encoding or decoding operation to remember any saved state from its previous invocation. Os métodos de classes derivados de Encoder e Decoder são capazes de lidar com as operações de codificação e decodificação que abrangem várias chamadas de método.Methods of classes derived from Encoder and Decoder are able to handle encoding and decoding operations that span multiple method calls.

Um objeto Encoder para uma codificação específica está disponível por meio da propriedade Encoding.GetEncoder da codificação.An Encoder object for a particular encoding is available from that encoding's Encoding.GetEncoder property. Um objeto Decoder para uma codificação específica está disponível por meio da propriedade Encoding.GetDecoder da codificação.A Decoder object for a particular encoding is available from that encoding's Encoding.GetDecoder property. Para operações de decodificação, observe que as classes derivadas de Decoder incluem um método Decoder.GetChars, mas não têm um método que corresponde a Encoding.GetString.For decoding operations, note that classes derived from Decoder include a Decoder.GetChars method, but they do not have a method that corresponds to Encoding.GetString.

O exemplo a seguir ilustra a diferença entre usar os métodos Encoding.GetChars e Decoder.GetChars para decodificar uma matriz de bytes Unicode.The following example illustrates the difference between using the Encoding.GetChars and Decoder.GetChars methods for decoding a Unicode byte array. O exemplo codifica uma cadeia de caracteres que contém alguns caracteres Unicode em um arquivo e, em seguida, usa os dois métodos de decodificação para decodificá-los dez bytes por vez.The example encodes a string that contains some Unicode characters to a file, and then uses the two decoding methods to decode them ten bytes at a time. Como um par alternativo ocorre nos bytes décimo e décimo primeiro, ele é decodificado em chamadas de método separadas.Because a surrogate pair occurs in the tenth and eleventh bytes, it is decoded in separate method calls. Como mostra a saída, o método Encoding.GetChars não é capaz de decodificar corretamente os bytes e, em vez disso, os substitui por U+FFFD (CARACTERE DE SUBSTITUIÇÃO).As the output shows, the Encoding.GetChars method is not able to correctly decode the bytes and instead replaces them with U+FFFD (REPLACEMENT CHARACTER). Por outro lado, o método Decoder.GetChars é capaz de decodificar com êxito a matriz de bytes para obter a cadeia de caracteres original.On the other hand, the Decoder.GetChars method is able to successfully decode the byte array to get the original string.

using System;
using System.IO;
using System.Text;

public class Example
{
   public static void Main()
   {
      // Use default replacement fallback for invalid encoding.
      UnicodeEncoding enc = new UnicodeEncoding(true, false, false);
      
      // Define a string with various Unicode characters.
      string str1 = "AB YZ 19 \uD800\udc05 \u00e4"; 
      str1 += "Unicode characters. \u00a9 \u010C s \u0062\u0308"; 
      Console.WriteLine("Created original string...\n");
      
      // Convert string to byte array.                     
      byte[] bytes = enc.GetBytes(str1);
       
      FileStream fs = File.Create(@".\characters.bin");
      BinaryWriter bw = new BinaryWriter(fs);
      bw.Write(bytes);
      bw.Close();
      
      // Read bytes from file.
      FileStream fsIn = File.OpenRead(@".\characters.bin");
      BinaryReader br = new BinaryReader(fsIn);
      
      const int count = 10;            // Number of bytes to read at a time. 
      byte[] bytesRead = new byte[10]; // Buffer (byte array).
      int read;                        // Number of bytes actually read. 
      string str2 = String.Empty;      // Decoded string.

      // Try using Encoding object for all operations.
      do { 
         read = br.Read(bytesRead, 0, count);
         str2 += enc.GetString(bytesRead, 0, read); 
      } while (read == count);
      br.Close();
      Console.WriteLine("Decoded string using UnicodeEncoding.GetString()...");
      CompareForEquality(str1, str2);
      Console.WriteLine();
      
      // Use Decoder for all operations.
      fsIn = File.OpenRead(@".\characters.bin");
      br = new BinaryReader(fsIn);
      Decoder decoder = enc.GetDecoder();
      char[] chars = new char[50];
      int index = 0;                   // Next character to write in array.
      int written = 0;                 // Number of chars written to array.
      do { 
         read = br.Read(bytesRead, 0, count);
         if (index + decoder.GetCharCount(bytesRead, 0, read) - 1 >= chars.Length) 
            Array.Resize(ref chars, chars.Length + 50);

         written = decoder.GetChars(bytesRead, 0, read, chars, index);
         index += written;                          
      } while (read == count);
      br.Close();            
      // Instantiate a string with the decoded characters.
      string str3 = new String(chars, 0, index); 
      Console.WriteLine("Decoded string using UnicodeEncoding.Decoder.GetString()...");
      CompareForEquality(str1, str3); 
   }

   private static void CompareForEquality(string original, string decoded)
   {
      bool result = original.Equals(decoded);
      Console.WriteLine("original = decoded: {0}", 
                        original.Equals(decoded, StringComparison.Ordinal));
      if (! result) {
         Console.WriteLine("Code points in original string:");
         foreach (var ch in original)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));
         Console.WriteLine();
         
         Console.WriteLine("Code points in decoded string:");
         foreach (var ch in decoded)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//    Created original string...
//    
//    Decoded string using UnicodeEncoding.GetString()...
//    original = decoded: False
//    Code points in original string:
//    0041 0042 0020 0059 005A 0020 0031 0039 0020 D800 DC05 0020 00E4 0055 006E 0069 0063 006F
//    0064 0065 0020 0063 0068 0061 0072 0061 0063 0074 0065 0072 0073 002E 0020 00A9 0020 010C
//    0020 0073 0020 0062 0308
//    Code points in decoded string:
//    0041 0042 0020 0059 005A 0020 0031 0039 0020 FFFD FFFD 0020 00E4 0055 006E 0069 0063 006F
//    0064 0065 0020 0063 0068 0061 0072 0061 0063 0074 0065 0072 0073 002E 0020 00A9 0020 010C
//    0020 0073 0020 0062 0308
//    
//    Decoded string using UnicodeEncoding.Decoder.GetString()...
//    original = decoded: True
Imports System.IO
Imports System.Text

Module Example
   Public Sub Main()
      ' Use default replacement fallback for invalid encoding.
      Dim enc As New UnicodeEncoding(True, False, False)
      
      ' Define a string with various Unicode characters.
      Dim str1 As String = String.Format("AB YZ 19 {0}{1} {2}", 
                                         ChrW(&hD800), ChrW(&hDC05), ChrW(&h00e4))
      str1 += String.Format("Unicode characters. {0} {1} s {2}{3}", 
                            ChrW(&h00a9), ChrW(&h010C), ChrW(&h0062), ChrW(&h0308))
      Console.WriteLine("Created original string...")
      Console.WriteLine()
      
      ' Convert string to byte array.                     
      Dim bytes() As Byte = enc.GetBytes(str1)
       
      Dim fs As FileStream = File.Create(".\characters.bin")
      Dim bw As New BinaryWriter(fs)
      bw.Write(bytes)
      bw.Close()
      
      ' Read bytes from file.
      Dim fsIn As FileStream = File.OpenRead(".\characters.bin")
      Dim br As New BinaryReader(fsIn)
      
      Const count As Integer = 10      ' Number of bytes to read at a time. 
      Dim bytesRead(9) As Byte         ' Buffer (byte array).
      Dim read As Integer              ' Number of bytes actually read. 
      Dim str2 As String = ""          ' Decoded string.

      ' Try using Encoding object for all operations.
      Do 
         read = br.Read(bytesRead, 0, count)
         str2 += enc.GetString(bytesRead, 0, read) 
      Loop While read = count
      br.Close()
      Console.WriteLine("Decoded string using UnicodeEncoding.GetString()...")
      CompareForEquality(str1, str2)
      Console.WriteLine()
      
      ' Use Decoder for all operations.
      fsIn = File.OpenRead(".\characters.bin")
      br = New BinaryReader(fsIn)
      Dim decoder As Decoder = enc.GetDecoder()
      Dim chars(50) As Char
      Dim index As Integer = 0         ' Next character to write in array.
      Dim written As Integer = 0       ' Number of chars written to array.
      Do 
         read = br.Read(bytesRead, 0, count)
         If index + decoder.GetCharCount(bytesRead, 0, read) - 1 >= chars.Length Then 
            Array.Resize(chars, chars.Length + 50)
         End If   
         written = decoder.GetChars(bytesRead, 0, read, chars, index)
         index += written                          
      Loop While read = count
      br.Close()            
      ' Instantiate a string with the decoded characters.
      Dim str3 As New String(chars, 0, index) 
      Console.WriteLine("Decoded string using UnicodeEncoding.Decoder.GetString()...")
      CompareForEquality(str1, str3) 
   End Sub
   
   Private Sub CompareForEquality(original As String, decoded As String)
      Dim result As Boolean = original.Equals(decoded)
      Console.WriteLine("original = decoded: {0}", 
                        original.Equals(decoded, StringComparison.Ordinal))
      If Not result Then
         Console.WriteLine("Code points in original string:")
         For Each ch In original
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next
         Console.WriteLine()
         
         Console.WriteLine("Code points in decoded string:")
         For Each ch In decoded
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next
         Console.WriteLine()
      End If
   End Sub
End Module
' The example displays the following output:
'    Created original string...
'    
'    Decoded string using UnicodeEncoding.GetString()...
'    original = decoded: False
'    Code points in original string:
'    0041 0042 0020 0059 005A 0020 0031 0039 0020 D800 DC05 0020 00E4 0055 006E 0069 0063 006F
'    0064 0065 0020 0063 0068 0061 0072 0061 0063 0074 0065 0072 0073 002E 0020 00A9 0020 010C
'    0020 0073 0020 0062 0308
'    Code points in decoded string:
'    0041 0042 0020 0059 005A 0020 0031 0039 0020 FFFD FFFD 0020 00E4 0055 006E 0069 0063 006F
'    0064 0065 0020 0063 0068 0061 0072 0061 0063 0074 0065 0072 0073 002E 0020 00A9 0020 010C
'    0020 0073 0020 0062 0308
'    
'    Decoded string using UnicodeEncoding.Decoder.GetString()...
'    original = decoded: True

Escolhendo uma estratégia de fallbackChoosing a Fallback Strategy

Quando um método tenta codificar ou decodificar um caractere, mas não existe nenhum mapeamento, ele deve implementar uma estratégia de fallback que determine como o mapeamento com falha deva ser tratado.When a method tries to encode or decode a character but no mapping exists, it must implement a fallback strategy that determines how the failed mapping should be handled. Há três tipos de estratégias de fallback:There are three types of fallback strategies:

  • Fallback de melhor ajusteBest-fit fallback

  • Fallback de substituiçãoReplacement fallback

  • Fallback de exceçãoException fallback

Importante

Os problemas mais comuns em operações de codificação ocorrem quando um caractere Unicode não pode ser mapeado para uma determinada codificação de página de código.The most common problems in encoding operations occur when a Unicode character cannot be mapped to a particular code page encoding. Os problemas mais comuns em operações de decodificação ocorrem quando sequências de bytes inválidas não podem ser convertidas em caracteres Unicode válidos.The most common problems in decoding operations occur when invalid byte sequences cannot be translated into valid Unicode characters. Por esses motivos, você deve saber qual estratégia de fallback um objeto de codificação específico usa.For these reasons, you should know which fallback strategy a particular encoding object uses. Sempre que possível, você deve especificar a estratégia de fallback usada por um objeto de codificação quando você criar uma instância do objeto.Whenever possible, you should specify the fallback strategy used by an encoding object when you instantiate the object.

Fallback de melhor ajusteBest-Fit Fallback

Quando um caractere não tiver uma correspondência exata na codificação de destino, o codificador pode tentar mapeá-lo para um caractere semelhante.When a character does not have an exact match in the target encoding, the encoder can try to map it to a similar character. (O fallback de melhor ajuste é sobretudo uma codificação em vez de um problema de decodificação.(Best-fit fallback is mostly an encoding rather than a decoding issue. Há poucas páginas de código que contêm caracteres que não podem ser mapeados com êxito para Unicode.) O melhor ajuste é o padrão para a página de código e codificações de conjunto de caracteres de byte duplo que são recuperadas pelo Encoding.GetEncoding(Int32) e Encoding.GetEncoding(String) sobrecargas.There are very few code pages that contain characters that cannot be successfully mapped to Unicode.) Best-fit fallback is the default for code page and double-byte character set encodings that are retrieved by the Encoding.GetEncoding(Int32) and Encoding.GetEncoding(String) overloads.

Observação

Na teoria, as classes de codificação Unicode fornecidas no .NET (UTF8Encoding, UnicodeEncoding e UTF32Encoding) dão suporte a todos os caracteres em cada conjunto de caracteres para que eles possam ser usados para eliminar problemas de fallback de melhor ajuste.In theory, the Unicode encoding classes provided in .NET (UTF8Encoding, UnicodeEncoding, and UTF32Encoding) support every character in every character set, so they can be used to eliminate best-fit fallback issues.

Estratégias de melhor ajuste variam para páginas de código diferentes.Best-fit strategies vary for different code pages. Por exemplo, para algumas páginas de código, caracteres latinos de largura inteira mapeiam para os caracteres latinos de meia largura mais comuns.For example, for some code pages, full-width Latin characters map to the more common half-width Latin characters. Para outras páginas de código, esse mapeamento não é feito.For other code pages, this mapping is not made. Mesmo em uma estratégia de melhor ajuste agressiva, não há nenhum ajuste imaginável para alguns caracteres em algumas codificações.Even under an aggressive best-fit strategy, there is no imaginable fit for some characters in some encodings. Por exemplo, um ideograma chinês tem nenhum mapeamento razoável para a página de código 1252.For example, a Chinese ideograph has no reasonable mapping to code page 1252. Nesse caso, é usada uma cadeia de caracteres de substituição.In this case, a replacement string is used. Por padrão, essa cadeia de caracteres é apenas um PONTO DE INTERROGAÇÃO (U+003F).By default, this string is just a single QUESTION MARK (U+003F).

Observação

Estratégias de melhor ajuste não estão documentadas em detalhes.Best-fit strategies are not documented in detail. No entanto, várias páginas de código estão documentadas no site do consórcio Unicode.However, several code pages are documented at the Unicode Consortium's website. Examine o arquivo leiame.txt nessa pasta para obter uma descrição de como interpretar os arquivos de mapeamento.Please review the readme.txt file in that folder for a description of how to interpret the mapping files.

O exemplo a seguir usa a página de código 1252 (a página de código do Windows para idiomas da Europa Ocidental) para ilustrar o mapeamento de melhor ajuste e suas desvantagens.The following example uses code page 1252 (the Windows code page for Western European languages) to illustrate best-fit mapping and its drawbacks. O método Encoding.GetEncoding(Int32) é usado para recuperar um objeto de codificação de página de código 1252.The Encoding.GetEncoding(Int32) method is used to retrieve an encoding object for code page 1252. Por padrão, ele usa um mapeamento de melhor ajuste para caracteres Unicode aos quais ele não dá suporte.By default, it uses a best-fit mapping for Unicode characters that it does not support. O exemplo cria uma instância de uma cadeia de caracteres que contém três caracteres não ASCII – LETRA MAIÚSCULA LATINA S CIRCULADA (U+24C8), CINCO SOBRESCRITO (U+2075) e INFINITO (U+221E) – separados por espaços.The example instantiates a string that contains three non-ASCII characters - CIRCLED LATIN CAPITAL LETTER S (U+24C8), SUPERSCRIPT FIVE (U+2075), and INFINITY (U+221E) - separated by spaces. Como mostra a saída de exemplo, quando a cadeia de caracteres é codificada, os três caracteres originais sem espaço são substituídos pelo PONTO DE INTERROGAÇÃO (U+003F), DÍGITO CINCO (U+0035) e DÍGITO OITO (U+0038).As the output from the example shows, when the string is encoded, the three original non-space characters are replaced by QUESTION MARK (U+003F), DIGIT FIVE (U+0035), and DIGIT EIGHT (U+0038). DÍGITO OITO é um substituto especialmente ruim para o caractere INFINITO sem suporte e o PONTO DE INTERROGAÇÃO indica que nenhum mapeamento estava disponível para o caractere original.DIGIT EIGHT is a particularly poor replacement for the unsupported INFINITY character, and QUESTION MARK indicates that no mapping was available for the original character.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      // Get an encoding for code page 1252 (Western Europe character set).
      Encoding cp1252 = Encoding.GetEncoding(1252);
      
      // Define and display a string.
      string str = "\u24c8 \u2075 \u221e";
      Console.WriteLine("Original string: " + str);
      Console.Write("Code points in string: ");
      foreach (var ch in str)
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

      Console.WriteLine("\n");   
      
      // Encode a Unicode string.
      Byte[] bytes = cp1252.GetBytes(str);
      Console.Write("Encoded bytes: ");
      foreach (byte byt in bytes)
         Console.Write("{0:X2} ", byt);
      Console.WriteLine("\n");
            
      // Decode the string.
      string str2 = cp1252.GetString(bytes);
      Console.WriteLine("String round-tripped: {0}", str.Equals(str2));
      if (! str.Equals(str2)) {
         Console.WriteLine(str2);
         foreach (var ch in str2)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));
      }
   }
}
// The example displays the following output:
//       Original string: Ⓢ ⁵ ∞
//       Code points in string: 24C8 0020 2075 0020 221E
//       
//       Encoded bytes: 3F 20 35 20 38
//       
//       String round-tripped: False
//       ? 5 8
//       003F 0020 0035 0020 0038
Imports System.Text

Module Example
   Public Sub Main()
      ' Get an encoding for code page 1252 (Western Europe character set).
      Dim cp1252 As Encoding = Encoding.GetEncoding(1252)
      
      ' Define and display a string.
      Dim str As String = String.Format("{0} {1} {2}", ChrW(&h24c8), ChrW(&H2075), ChrW(&h221E))
      Console.WriteLine("Original string: " + str)
      Console.Write("Code points in string: ")
      For Each ch In str
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
      Next
      Console.WriteLine()   
      Console.WriteLine()
      
      ' Encode a Unicode string.
      Dim bytes() As Byte = cp1252.GetBytes(str)
      Console.Write("Encoded bytes: ")
      For Each byt In bytes
         Console.Write("{0:X2} ", byt)
      Next
      Console.WriteLine()
      Console.WriteLine()
      
      ' Decode the string.
      Dim str2 As String = cp1252.GetString(bytes)
      Console.WriteLine("String round-tripped: {0}", str.Equals(str2))
      If Not str.Equals(str2) Then
         Console.WriteLine(str2)
         For Each ch In str2
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next
      End If
   End Sub
End Module
' The example displays the following output:
'       Original string: Ⓢ ⁵ ∞
'       Code points in string: 24C8 0020 2075 0020 221E
'       
'       Encoded bytes: 3F 20 35 20 38
'       
'       String round-tripped: False
'       ? 5 8
'       003F 0020 0035 0020 0038

O mapeamento de melhor ajuste é o comportamento padrão para um objeto Encoding que codifica dados Unicode em dados da página de código e há aplicativos herdados que se baseiam nesse comportamento.Best-fit mapping is the default behavior for an Encoding object that encodes Unicode data into code page data, and there are legacy applications that rely on this behavior. No entanto, a maioria dos novos aplicativos devem evitar o comportamento de melhor ajuste por motivos de segurança.However, most new applications should avoid best-fit behavior for security reasons. Por exemplo, os aplicativos não devem colocar um nome de domínio por meio de uma codificação de melhor ajuste.For example, applications should not put a domain name through a best-fit encoding.

Observação

Você também pode implementar um mapeamento de fallback de melhor ajuste personalizado para uma codificação.You can also implement a custom best-fit fallback mapping for an encoding. Para obter mais informações, consulte a seção Implementando uma estratégia de fallback personalizada.For more information, see the Implementing a Custom Fallback Strategy section.

Se o fallback mais adequado for o padrão para um objeto de codificação, você poderá escolher outra estratégia de fallback ao recuperar um objeto Encoding chamando a sobrecarga Encoding.GetEncoding(Int32, EncoderFallback, DecoderFallback) ou Encoding.GetEncoding(String, EncoderFallback, DecoderFallback).If best-fit fallback is the default for an encoding object, you can choose another fallback strategy when you retrieve an Encoding object by calling the Encoding.GetEncoding(Int32, EncoderFallback, DecoderFallback) or Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) overload. A seção a seguir inclui um exemplo que substitui cada caractere que não pode ser mapeado para a página de código 1252 com um asterisco (*).The following section includes an example that replaces each character that cannot be mapped to code page 1252 with an asterisk (*).

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      Encoding cp1252r = Encoding.GetEncoding(1252, 
                                  new EncoderReplacementFallback("*"),
                                  new DecoderReplacementFallback("*"));
      
      string str1 = "\u24C8 \u2075 \u221E";
      Console.WriteLine(str1);
      foreach (var ch in str1)
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

      Console.WriteLine();

      byte[] bytes = cp1252r.GetBytes(str1);
      string str2 = cp1252r.GetString(bytes);
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2));
      if (! str1.Equals(str2)) {
         Console.WriteLine(str2);
         foreach (var ch in str2)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

         Console.WriteLine();
      } 
   }
}
// The example displays the following output:
//       Ⓢ ⁵ ∞
//       24C8 0020 2075 0020 221E
//       Round-trip: False
//       * * *
//       002A 0020 002A 0020 002A
Imports System.Text

Module Example
   Public Sub Main()
      Dim cp1252r As Encoding = Encoding.GetEncoding(1252, 
                                         New EncoderReplacementFallback("*"),
                                         New DecoderReplacementFallback("*"))
      
      Dim str1 As String = String.Format("{0} {1} {2}", ChrW(&h24C8), ChrW(&h2075), ChrW(&h221E))
      Console.WriteLine(str1)
      For Each ch In str1
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
      Next    
      Console.WriteLine()

      Dim bytes() As Byte = cp1252r.GetBytes(str1)
      Dim str2 As String = cp1252r.GetString(bytes)
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2))
      If Not str1.Equals(str2) Then
         Console.WriteLine(str2)
         For Each ch In str2
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next    
         Console.WriteLine()
      End If 
   End Sub
End Module
' The example displays the following output:
'       Ⓢ ⁵ ∞
'       24C8 0020 2075 0020 221E
'       Round-trip: False
'       * * *
'       002A 0020 002A 0020 002A

Fallback de substituiçãoReplacement Fallback

Quando um caractere não tem uma correspondência exata do esquema de destino, mas não há nenhum caractere apropriado para o qual ele pode ser mapeado, o aplicativo pode especificar um caractere ou uma cadeia de caracteres de substituição.When a character does not have an exact match in the target scheme, but there is no appropriate character that it can be mapped to, the application can specify a replacement character or string. Esse é o comportamento padrão para o decodificador de Unicode, que substitui qualquer sequência de dois bytes que ele não pode decodificar por REPLACEMENT_CHARACTER (U+FFFD).This is the default behavior for the Unicode decoder, which replaces any two-byte sequence that it cannot decode with REPLACEMENT_CHARACTER (U+FFFD). Também é o comportamento padrão da classe ASCIIEncoding, que substitui cada caractere que ela não pode codificar ou decodificar por um ponto de interrogação.It is also the default behavior of the ASCIIEncoding class, which replaces each character that it cannot encode or decode with a question mark. O exemplo a seguir ilustra a substituição de caracteres para a cadeia de caracteres Unicode do exemplo anterior.The following example illustrates character replacement for the Unicode string from the previous example. Como mostra a saída, cada caractere que não puder ser decodificado em um valor de bytes ASCII é substituído por 0x3F, que é o código ASCII para um ponto de interrogação.As the output shows, each character that cannot be decoded into an ASCII byte value is replaced by 0x3F, which is the ASCII code for a question mark.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      Encoding enc = Encoding.ASCII;
      
      string str1 = "\u24C8 \u2075 \u221E";
      Console.WriteLine(str1);
      foreach (var ch in str1)
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

      Console.WriteLine("\n");

      // Encode the original string using the ASCII encoder.
      byte[] bytes = enc.GetBytes(str1);
      Console.Write("Encoded bytes: ");
      foreach (var byt in bytes)
         Console.Write("{0:X2} ", byt);
      Console.WriteLine("\n");

      // Decode the ASCII bytes.
      string str2 = enc.GetString(bytes);
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2));
      if (! str1.Equals(str2)) {
         Console.WriteLine(str2);
         foreach (var ch in str2)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

         Console.WriteLine();
      } 
   }
}
// The example displays the following output:
//       Ⓢ ⁵ ∞
//       24C8 0020 2075 0020 221E
//       
//       Encoded bytes: 3F 20 3F 20 3F
//       
//       Round-trip: False
//       ? ? ?
//       003F 0020 003F 0020 003F
Imports System.Text

Module Example
   Public Sub Main()
      Dim enc As Encoding = Encoding.Ascii
      
      Dim str1 As String = String.Format("{0} {1} {2}", ChrW(&h24C8), ChrW(&h2075), ChrW(&h221E))
      Console.WriteLine(str1)
      For Each ch In str1
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
      Next    
      Console.WriteLine()
      Console.WriteLine() 

      ' Encode the original string using the ASCII encoder.
      Dim bytes() As Byte = enc.GetBytes(str1)
      Console.Write("Encoded bytes: ")
      For Each byt In bytes
         Console.Write("{0:X2} ", byt)
      Next
      Console.WriteLine()
      Console.WriteLine()

      ' Decode the ASCII bytes.
      Dim str2 As String = enc.GetString(bytes)
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2))
      If Not str1.Equals(str2) Then
         Console.WriteLine(str2)
         For Each ch In str2
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next    
         Console.WriteLine()
      End If 
   End Sub
End Module
' The example displays the following output:
'       Ⓢ ⁵ ∞
'       24C8 0020 2075 0020 221E
'       
'       Encoded bytes: 3F 20 3F 20 3F
'       
'       Round-trip: False
'       ? ? ?
'       003F 0020 003F 0020 003F

O .NET inclui as classes EncoderReplacementFallback e DecoderReplacementFallback, que substituem uma cadeia de caracteres de substituição se um caractere não é mapeado exatamente em uma operação de codificação ou decodificação..NET includes the EncoderReplacementFallback and DecoderReplacementFallback classes, which substitute a replacement string if a character does not map exactly in an encoding or decoding operation. Por padrão, essa cadeia de caracteres de substituição é um ponto de interrogação, mas você pode chamar uma sobrecarga do construtor de classes para escolher uma cadeia de caracteres diferente.By default, this replacement string is a question mark, but you can call a class constructor overload to choose a different string. Normalmente, a cadeia de caracteres de substituição é um único caractere, embora isso não seja um requisito.Typically, the replacement string is a single character, although this is not a requirement. O exemplo a seguir altera o comportamento do codificador da página de código 1252 criando uma instância de um objeto EncoderReplacementFallback que usa um asterisco (*) como uma cadeia de caracteres de substituição.The following example changes the behavior of the code page 1252 encoder by instantiating an EncoderReplacementFallback object that uses an asterisk (*) as a replacement string.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      Encoding cp1252r = Encoding.GetEncoding(1252, 
                                  new EncoderReplacementFallback("*"),
                                  new DecoderReplacementFallback("*"));
      
      string str1 = "\u24C8 \u2075 \u221E";
      Console.WriteLine(str1);
      foreach (var ch in str1)
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

      Console.WriteLine();

      byte[] bytes = cp1252r.GetBytes(str1);
      string str2 = cp1252r.GetString(bytes);
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2));
      if (! str1.Equals(str2)) {
         Console.WriteLine(str2);
         foreach (var ch in str2)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

         Console.WriteLine();
      } 
   }
}
// The example displays the following output:
//       Ⓢ ⁵ ∞
//       24C8 0020 2075 0020 221E
//       Round-trip: False
//       * * *
//       002A 0020 002A 0020 002A
Imports System.Text

Module Example
   Public Sub Main()
      Dim cp1252r As Encoding = Encoding.GetEncoding(1252, 
                                         New EncoderReplacementFallback("*"),
                                         New DecoderReplacementFallback("*"))
      
      Dim str1 As String = String.Format("{0} {1} {2}", ChrW(&h24C8), ChrW(&h2075), ChrW(&h221E))
      Console.WriteLine(str1)
      For Each ch In str1
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
      Next    
      Console.WriteLine()

      Dim bytes() As Byte = cp1252r.GetBytes(str1)
      Dim str2 As String = cp1252r.GetString(bytes)
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2))
      If Not str1.Equals(str2) Then
         Console.WriteLine(str2)
         For Each ch In str2
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next    
         Console.WriteLine()
      End If 
   End Sub
End Module
' The example displays the following output:
'       Ⓢ ⁵ ∞
'       24C8 0020 2075 0020 221E
'       Round-trip: False
'       * * *
'       002A 0020 002A 0020 002A

Observação

Você também pode implementar uma classe de substituição para uma codificação.You can also implement a replacement class for an encoding. Para obter mais informações, consulte a seção Implementando uma estratégia de fallback personalizada.For more information, see the Implementing a Custom Fallback Strategy section.

Além de PONTO DE INTERROGAÇÃO (U+003F), o CARACTERE DE SUBSTITUIÇÃO Unicode (U+FFFD) normalmente é usado como uma cadeia de caracteres de substituição, especialmente ao decodificar sequências de bytes que não podem ser convertidas com êxito em caracteres Unicode.In addition to QUESTION MARK (U+003F), the Unicode REPLACEMENT CHARACTER (U+FFFD) is commonly used as a replacement string, particularly when decoding byte sequences that cannot be successfully translated into Unicode characters. No entanto, você está livre para escolher qualquer cadeia de caracteres de substituição e ela pode conter vários caracteres.However, you are free to choose any replacement string, and it can contain multiple characters.

Fallback de exceçãoException Fallback

Em vez de oferecer um fallback de melhor ajuste ou uma cadeia de caracteres de substituição, um codificador pode lançar uma EncoderFallbackException se não for possível codificar um conjunto de caracteres e um decodificador pode lançar uma DecoderFallbackException se não for possível decodificar uma matriz de bytes.Instead of providing a best-fit fallback or a replacement string, an encoder can throw an EncoderFallbackException if it is unable to encode a set of characters, and a decoder can throw a DecoderFallbackException if it is unable to decode a byte array. Para gerar uma exceção em operações de codificação e decodificação, você deve fornecer um objeto EncoderExceptionFallback e um objeto DecoderExceptionFallback, respectivamente, para o método Encoding.GetEncoding(String, EncoderFallback, DecoderFallback).To throw an exception in encoding and decoding operations, you supply an EncoderExceptionFallback object and a DecoderExceptionFallback object, respectively, to the Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) method. O exemplo a seguir ilustra a o fallback de exceção com a classe ASCIIEncoding.The following example illustrates exception fallback with the ASCIIEncoding class.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      Encoding enc = Encoding.GetEncoding("us-ascii", 
                                          new EncoderExceptionFallback(), 
                                          new DecoderExceptionFallback());
      
      string str1 = "\u24C8 \u2075 \u221E";
      Console.WriteLine(str1);
      foreach (var ch in str1)
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

      Console.WriteLine("\n");

      // Encode the original string using the ASCII encoder.
      byte[] bytes = {};
      try {
         bytes = enc.GetBytes(str1);
         Console.Write("Encoded bytes: ");
         foreach (var byt in bytes)
            Console.Write("{0:X2} ", byt);

         Console.WriteLine();
      }
      catch (EncoderFallbackException e) {
         Console.Write("Exception: ");
         if (e.IsUnknownSurrogate())
            Console.WriteLine("Unable to encode surrogate pair 0x{0:X4} 0x{1:X3} at index {2}.", 
                              Convert.ToUInt16(e.CharUnknownHigh), 
                              Convert.ToUInt16(e.CharUnknownLow), 
                              e.Index);
         else
            Console.WriteLine("Unable to encode 0x{0:X4} at index {1}.", 
                              Convert.ToUInt16(e.CharUnknown), 
                              e.Index);
         return;
      }
      Console.WriteLine();

      // Decode the ASCII bytes.
      try {
         string str2 = enc.GetString(bytes);
         Console.WriteLine("Round-trip: {0}", str1.Equals(str2));
         if (! str1.Equals(str2)) {
            Console.WriteLine(str2);
            foreach (var ch in str2)
               Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

            Console.WriteLine();
         } 
      }
      catch (DecoderFallbackException e) {
         Console.Write("Unable to decode byte(s) ");
         foreach (byte unknown in e.BytesUnknown)
            Console.Write("0x{0:X2} ");

         Console.WriteLine("at index {0}", e.Index);
      }
   }
}
// The example displays the following output:
//       Ⓢ ⁵ ∞
//       24C8 0020 2075 0020 221E
//       
//       Exception: Unable to encode 0x24C8 at index 0.
Imports System.Text

Module Example
   Public Sub Main()
      Dim enc As Encoding = Encoding.GetEncoding("us-ascii", 
                                                 New EncoderExceptionFallback(), 
                                                 New DecoderExceptionFallback())
      
      Dim str1 As String = String.Format("{0} {1} {2}", ChrW(&h24C8), ChrW(&h2075), ChrW(&h221E))
      Console.WriteLine(str1)
      For Each ch In str1
         Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
      Next    
      Console.WriteLine()
      Console.WriteLine() 

      ' Encode the original string using the ASCII encoder.
      Dim bytes() As Byte = {}
      Try
         bytes = enc.GetBytes(str1)
         Console.Write("Encoded bytes: ")
         For Each byt In bytes
            Console.Write("{0:X2} ", byt)
         Next
         Console.WriteLine()
      Catch e As EncoderFallbackException
         Console.Write("Exception: ")
         If e.IsUnknownSurrogate() Then
            Console.WriteLine("Unable to encode surrogate pair 0x{0:X4} 0x{1:X3} at index {2}.", 
                              Convert.ToUInt16(e.CharUnknownHigh), 
                              Convert.ToUInt16(e.CharUnknownLow), 
                              e.Index)
         Else
            Console.WriteLine("Unable to encode 0x{0:X4} at index {1}.", 
                              Convert.ToUInt16(e.CharUnknown), 
                              e.Index)
         End If                              
         Exit Sub
      End Try
      Console.WriteLine()

      ' Decode the ASCII bytes.
      Try
         Dim str2 As String = enc.GetString(bytes)
         Console.WriteLine("Round-trip: {0}", str1.Equals(str2))
         If Not str1.Equals(str2) Then
            Console.WriteLine(str2)
            For Each ch In str2
               Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
            Next    
            Console.WriteLine()
         End If 
      Catch e As DecoderFallbackException
         Console.Write("Unable to decode byte(s) ")
         For Each unknown As Byte In e.BytesUnknown
            Console.Write("0x{0:X2} ")
         Next
         Console.WriteLine("at index {0}", e.Index)
      End Try
   End Sub
End Module
' The example displays the following output:
'       Ⓢ ⁵ ∞
'       24C8 0020 2075 0020 221E
'       
'       Exception: Unable to encode 0x24C8 at index 0.

Observação

Você também pode implementar um manipulador de exceção personalizado para uma operação de codificação.You can also implement a custom exception handler for an encoding operation. Para obter mais informações, consulte a seção Implementando uma estratégia de fallback personalizada.For more information, see the Implementing a Custom Fallback Strategy section.

Os objetos EncoderFallbackException e DecoderFallbackException fornecem as seguintes informações sobre a condição que causou a exceção:The EncoderFallbackException and DecoderFallbackException objects provide the following information about the condition that caused the exception:

Embora os objetos EncoderFallbackException e DecoderFallbackException forneçam informações de diagnóstico adequadas sobre a exceção, eles não fornecem acesso ao buffer de codificação ou decodificação.Although the EncoderFallbackException and DecoderFallbackException objects provide adequate diagnostic information about the exception, they do not provide access to the encoding or decoding buffer. Portanto, eles não permitem que dados inválidos sejam substituídos ou corrigidos dentro do método de codificação ou de decodificação.Therefore, they do not allow invalid data to be replaced or corrected within the encoding or decoding method.

Implementando uma estratégia de fallback personalizadaImplementing a Custom Fallback Strategy

Além do mapeamento de melhor ajuste implementado internamente por páginas de código, o .NET inclui as seguintes classes para implementar uma estratégia de fallback:In addition to the best-fit mapping that is implemented internally by code pages, .NET includes the following classes for implementing a fallback strategy:

Além disso, você pode implementar uma solução personalizada que usa o fallback de melhor ajuste, fallback de substituição ou fallback de exceção seguindo estas etapas:In addition, you can implement a custom solution that uses best-fit fallback, replacement fallback, or exception fallback, by following these steps:

  1. Derive uma classe de EncoderFallback para operações de codificação e de DecoderFallback para operações de decodificação.Derive a class from EncoderFallback for encoding operations, and from DecoderFallback for decoding operations.

  2. Derive uma classe de EncoderFallbackBuffer para operações de codificação e de DecoderFallbackBuffer para operações de decodificação.Derive a class from EncoderFallbackBuffer for encoding operations, and from DecoderFallbackBuffer for decoding operations.

  3. Para o fallback de exceção, se as classes predefinidas EncoderFallbackException e DecoderFallbackException não atenderem às suas necessidades, derive uma classe de um objeto de exceção como Exception ou ArgumentException.For exception fallback, if the predefined EncoderFallbackException and DecoderFallbackException classes do not meet your needs, derive a class from an exception object such as Exception or ArgumentException.

Derivando de EncoderFallback ou DecoderFallbackDeriving from EncoderFallback or DecoderFallback

Para implementar uma solução de fallback personalizada, você deverá criar uma classe herdada de EncoderFallback para operações de codificação e de DecoderFallback para operações de decodificação.To implement a custom fallback solution, you must create a class that inherits from EncoderFallback for encoding operations, and from DecoderFallback for decoding operations. As instâncias dessas classes são passadas para o método Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) e servem como um intermediário entre a classe de codificação e a implementação de fallback.Instances of these classes are passed to the Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) method and serve as the intermediary between the encoding class and the fallback implementation.

Quando você cria uma solução de fallback personalizada para um codificador ou um decodificador, você deve implementar os seguintes membros:When you create a custom fallback solution for an encoder or decoder, you must implement the following members:

Derivando de EncoderFallbackBuffer ou DecoderFallbackBufferDeriving from EncoderFallbackBuffer or DecoderFallbackBuffer

Para implementar uma solução de fallback personalizada, você deverá criar também uma classe herdada de EncoderFallbackBuffer para operações de codificação e de DecoderFallbackBuffer para operações de decodificação.To implement a custom fallback solution, you must also create a class that inherits from EncoderFallbackBuffer for encoding operations, and from DecoderFallbackBuffer for decoding operations. As instâncias dessas classes são retornadas pelo método CreateFallbackBuffer das classes EncoderFallback e DecoderFallback.Instances of these classes are returned by the CreateFallbackBuffer method of the EncoderFallback and DecoderFallback classes. O método EncoderFallback.CreateFallbackBuffer é chamado pelo codificador quando ele encontra o primeiro caractere que ele não consegue codificar e o método DecoderFallback.CreateFallbackBuffer é chamado pelo decodificador quando ele encontra um ou mais bytes que ele não consegue decodificar.The EncoderFallback.CreateFallbackBuffer method is called by the encoder when it encounters the first character that it is not able to encode, and the DecoderFallback.CreateFallbackBuffer method is called by the decoder when it encounters one or more bytes that it is not able to decode. As classes EncoderFallbackBuffer e DecoderFallbackBuffer fornecem a implementação de fallback.The EncoderFallbackBuffer and DecoderFallbackBuffer classes provide the fallback implementation. Cada instância representa um buffer que contém os caracteres de fallback que substituirão o caractere que não pode ser codificado ou a sequência de bytes que não pode ser decodificada.Each instance represents a buffer that contains the fallback characters that will replace the character that cannot be encoded or the byte sequence that cannot be decoded.

Quando você cria uma solução de fallback personalizada para um codificador ou um decodificador, você deve implementar os seguintes membros:When you create a custom fallback solution for an encoder or decoder, you must implement the following members:

Se a implementação de fallback for um fallback de melhor ajuste ou de substituição, as classes derivadas de EncoderFallbackBuffer e DecoderFallbackBuffer também mantêm dois campos de instância privados: o número exato de caracteres no buffer e o índice do próximo caractere no buffer a ser retornado.If the fallback implementation is a best-fit fallback or a replacement fallback, the classes derived from EncoderFallbackBuffer and DecoderFallbackBuffer also maintain two private instance fields: the exact number of characters in the buffer; and the index of the next character in the buffer to return.

Um exemplo de EncoderFallbackAn EncoderFallback Example

Um exemplo anterior usava o fallback de substituição para substituir caracteres Unicode que não correspondiam aos caracteres ASCII por um asterisco (*).An earlier example used replacement fallback to replace Unicode characters that did not correspond to ASCII characters with an asterisk (*). O exemplo a seguir usa uma implementação de fallback de melhor ajuste personalizada em vez de fornecer um melhor mapeamento de caracteres não ASCII.The following example uses a custom best-fit fallback implementation instead to provide a better mapping of non-ASCII characters.

O código a seguir define uma classe chamada CustomMapper derivada de EncoderFallback para lidar com o mapeamento de melhor ajuste de caracteres não ASCII.The following code defines a class named CustomMapper that is derived from EncoderFallback to handle the best-fit mapping of non-ASCII characters. Seu método CreateFallbackBuffer retorna um objeto CustomMapperFallbackBuffer, que fornece a implementação EncoderFallbackBuffer.Its CreateFallbackBuffer method returns a CustomMapperFallbackBuffer object, which provides the EncoderFallbackBuffer implementation. A classe CustomMapper usa um objeto Dictionary<TKey,TValue> para armazenar os mapeamentos de caracteres Unicode sem suporte (o valor da chave) e seus caracteres de 8 bits correspondentes (armazenados em dois bytes consecutivos em um inteiro de 64 bits).The CustomMapper class uses a Dictionary<TKey,TValue> object to store the mappings of unsupported Unicode characters (the key value) and their corresponding 8-bit characters (which are stored in two consecutive bytes in a 64-bit integer). Para disponibilizar esse mapeamento ao buffer de fallback, a instância CustomMapper é passada como um parâmetro para o construtor de classe CustomMapperFallbackBuffer.To make this mapping available to the fallback buffer, the CustomMapper instance is passed as a parameter to the CustomMapperFallbackBuffer class constructor. Como o mapeamento mais longo é a cadeia de caracteres "INF" para o caractere Unicode U+221E, a propriedade MaxCharCount retorna 3.Because the longest mapping is the string "INF" for the Unicode character U+221E, the MaxCharCount property returns 3.

public class CustomMapper : EncoderFallback
{
   public string DefaultString;
   internal Dictionary<ushort, ulong> mapping;

   public CustomMapper() : this("*")
   {   
   }
   
   public CustomMapper(string defaultString)
   {
      this.DefaultString = defaultString;

      // Create table of mappings
      mapping = new Dictionary<ushort, ulong>();
      mapping.Add(0x24C8, 0x53);
      mapping.Add(0x2075, 0x35);
      mapping.Add(0x221E, 0x49004E0046);
   }

   public override EncoderFallbackBuffer CreateFallbackBuffer()
   {
      return new CustomMapperFallbackBuffer(this);
   }

   public override int MaxCharCount
   {
      get { return 3; }
   } 
}
Public Class CustomMapper : Inherits EncoderFallback
   Public DefaultString As String
   Friend mapping As Dictionary(Of UShort, ULong)

   Public Sub New()
      Me.New("?")
   End Sub

   Public Sub New(ByVal defaultString As String)
      Me.DefaultString = defaultString

      ' Create table of mappings
      mapping = New Dictionary(Of UShort, ULong)
      mapping.Add(&H24C8, &H53)
      mapping.Add(&H2075, &H35)
      mapping.Add(&H221E, &H49004E0046)
   End Sub

   Public Overrides Function CreateFallbackBuffer() As System.Text.EncoderFallbackBuffer
      Return New CustomMapperFallbackBuffer(Me)
   End Function

   Public Overrides ReadOnly Property MaxCharCount As Integer
      Get
         Return 3
      End Get
   End Property
End Class

O código a seguir define a classe CustomMapperFallbackBuffer, derivada de EncoderFallbackBuffer.The following code defines the CustomMapperFallbackBuffer class, which is derived from EncoderFallbackBuffer. O dicionário que contém mapeamentos de melhor ajuste e definido na instância CustomMapper está disponível no seu construtor de classe.The dictionary that contains best-fit mappings and that is defined in the CustomMapper instance is available from its class constructor. Seu método Fallback retornará true se qualquer um dos caracteres Unicode que o codificador ASCII não conseguir codificar forem definidos no dicionário de mapeamento; caso contrário, retornará false.Its Fallback method returns true if any of the Unicode characters that the ASCII encoder cannot encode are defined in the mapping dictionary; otherwise, it returns false. Para cada fallback, a variável count privada indica o número de caracteres que continuam sendo retornados e a variável index privada indica a posição no buffer de cadeia de caracteres, charsToReturn, do próximo caractere a ser retornado.For each fallback, the private count variable indicates the number of characters that remain to be returned, and the private index variable indicates the position in the string buffer, charsToReturn, of the next character to return.

public class CustomMapperFallbackBuffer : EncoderFallbackBuffer
{
   int count = -1;                   // Number of characters to return
   int index = -1;                   // Index of character to return
   CustomMapper fb; 
   string charsToReturn; 

   public CustomMapperFallbackBuffer(CustomMapper fallback)
   {
      this.fb = fallback;
   }

   public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index)
   {
      // Do not try to map surrogates to ASCII.
      return false;
   }

   public override bool Fallback(char charUnknown, int index)
   {
      // Return false if there are already characters to map.
      if (count >= 1) return false;

      // Determine number of characters to return.
      charsToReturn = String.Empty;

      ushort key = Convert.ToUInt16(charUnknown);
      if (fb.mapping.ContainsKey(key)) {
         byte[] bytes = BitConverter.GetBytes(fb.mapping[key]);
         int ctr = 0;
         foreach (var byt in bytes) {
            if (byt > 0) {
               ctr++;
               charsToReturn += (char) byt;
            }
         }
         count = ctr;
      }
      else {
         // Return default.
         charsToReturn = fb.DefaultString;
         count = 1;
      }
      this.index = charsToReturn.Length - 1;

      return true;
   }

   public override char GetNextChar()
   {
      // We'll return a character if possible, so subtract from the count of chars to return.
      count--;
      // If count is less than zero, we've returned all characters.
      if (count < 0) 
         return '\u0000';

      this.index--;
      return charsToReturn[this.index + 1];
   }

   public override bool MovePrevious()
   {
      // Original: if count >= -1 and pos >= 0
      if (count >= -1) {
         count++;
         return true;
      }
      else {
         return false;
      }
   }

   public override int Remaining 
   {
      get { return count < 0 ? 0 : count; }
   }

   public override void Reset()
   {
      count = -1;
      index = -1;
   }
}
Public Class CustomMapperFallbackBuffer : Inherits EncoderFallbackBuffer

   Dim count As Integer = -1        ' Number of characters to return
   Dim index As Integer = -1        ' Index of character to return
   Dim fb As CustomMapper
   Dim charsToReturn As String

   Public Sub New(ByVal fallback As CustomMapper)
      MyBase.New()
      Me.fb = fallback
   End Sub

   Public Overloads Overrides Function Fallback(ByVal charUnknownHigh As Char, ByVal charUnknownLow As Char, ByVal index As Integer) As Boolean
      ' Do not try to map surrogates to ASCII.
      Return False
   End Function

   Public Overloads Overrides Function Fallback(ByVal charUnknown As Char, ByVal index As Integer) As Boolean
      ' Return false if there are already characters to map.
      If count >= 1 Then Return False

      ' Determine number of characters to return.
      charsToReturn = String.Empty

      Dim key As UShort = Convert.ToUInt16(charUnknown)
      If fb.mapping.ContainsKey(key) Then
         Dim bytes() As Byte = BitConverter.GetBytes(fb.mapping.Item(key))
         Dim ctr As Integer
         For Each byt In bytes
            If byt > 0 Then
               ctr += 1
               charsToReturn += Chr(byt)
            End If
         Next
         count = ctr
      Else
         ' Return default.
         charsToReturn = fb.DefaultString
         count = 1
      End If
      Me.index = charsToReturn.Length - 1

      Return True
   End Function

   Public Overrides Function GetNextChar() As Char
      ' We'll return a character if possible, so subtract from the count of chars to return.
      count -= 1
      ' If count is less than zero, we've returned all characters.
      If count < 0 Then Return ChrW(0)

      Me.index -= 1
      Return charsToReturn(Me.index + 1)
   End Function

   Public Overrides Function MovePrevious() As Boolean
      ' Original: if count >= -1 and pos >= 0
      If count >= -1 Then
         count += 1
         Return True
      Else
         Return False
      End If
   End Function

   Public Overrides ReadOnly Property Remaining As Integer
      Get
         Return If(count < 0, 0, count)
      End Get
   End Property

   Public Overrides Sub Reset()
      count = -1
      index = -1
   End Sub
End Class

O código a seguir instancia o objeto CustomMapper e passa uma instância dele para o método Encoding.GetEncoding(String, EncoderFallback, DecoderFallback).The following code then instantiates the CustomMapper object and passes an instance of it to the Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) method. A saída indica que a implementação de fallback de melhor ajuste lida com êxito com os três caracteres não ASCII na cadeia de caracteres original.The output indicates that the best-fit fallback implementation successfully handles the three non-ASCII characters in the original string.

using System;
using System.Collections.Generic;
using System.Text;

class Program
{
   static void Main()
   {
      Encoding enc = Encoding.GetEncoding("us-ascii", new CustomMapper(), new DecoderExceptionFallback());

      string str1 = "\u24C8 \u2075 \u221E";
      Console.WriteLine(str1);
      for (int ctr = 0; ctr <= str1.Length - 1; ctr++) {
         Console.Write("{0} ", Convert.ToUInt16(str1[ctr]).ToString("X4"));
         if (ctr == str1.Length - 1) 
            Console.WriteLine();
      }
      Console.WriteLine();

      // Encode the original string using the ASCII encoder.
      byte[] bytes = enc.GetBytes(str1);
      Console.Write("Encoded bytes: ");
      foreach (var byt in bytes)
         Console.Write("{0:X2} ", byt);

      Console.WriteLine("\n");

      // Decode the ASCII bytes.
      string str2 = enc.GetString(bytes);
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2));
      if (! str1.Equals(str2)) {
         Console.WriteLine(str2);
         foreach (var ch in str2)
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"));

         Console.WriteLine();
      }
   }
}
Imports System.Text
Imports System.Collections.Generic

Module Module1

   Sub Main()
      Dim enc As Encoding = Encoding.GetEncoding("us-ascii", New CustomMapper(), New DecoderExceptionFallback())

      Dim str1 As String = String.Format("{0} {1} {2}", ChrW(&H24C8), ChrW(&H2075), ChrW(&H221E))
      Console.WriteLine(str1)
      For ctr As Integer = 0 To str1.Length - 1
         Console.Write("{0} ", Convert.ToUInt16(str1(ctr)).ToString("X4"))
         If ctr = str1.Length - 1 Then Console.WriteLine()
      Next
      Console.WriteLine()

      ' Encode the original string using the ASCII encoder.
      Dim bytes() As Byte = enc.GetBytes(str1)
      Console.Write("Encoded bytes: ")
      For Each byt In bytes
         Console.Write("{0:X2} ", byt)
      Next
      Console.WriteLine()
      Console.WriteLine()

      ' Decode the ASCII bytes.
      Dim str2 As String = enc.GetString(bytes)
      Console.WriteLine("Round-trip: {0}", str1.Equals(str2))
      If Not str1.Equals(str2) Then
         Console.WriteLine(str2)
         For Each ch In str2
            Console.Write("{0} ", Convert.ToUInt16(ch).ToString("X4"))
         Next
         Console.WriteLine()
      End If
   End Sub
End Module

Veja tambémSee also