Codificación de caracteres de .NETCharacter Encoding in .NET

Los caracteres son entidades abstractas que se pueden representar de muchas maneras diferentes.Characters are abstract entities that can be represented in many different ways. Una codificación de caracteres es un sistema que empareja cada carácter de un juego de caracteres compatible con algún valor que representa ese carácter.A character encoding is a system that pairs each character in a supported character set with some value that represents that character. Por ejemplo, el código Morse es una codificación de caracteres que empareja cada carácter del alfabeto latino con un patrón de puntos y guiones que son adecuados para la transmisión a través de las líneas de telégrafo.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. Una codificación de caracteres para los equipos empareja cada carácter de un juego de caracteres compatible con un valor numérico que representa ese carácter.A character encoding for computers pairs each character in a supported character set with a numeric value that represents that character. Una codificación de caracteres tiene dos componentes distintos:A character encoding has two distinct components:

  • Un codificador, que traduce una secuencia de caracteres en una secuencia de valores numéricos (bytes).An encoder, which translates a sequence of characters into a sequence of numeric values (bytes).

  • Un descodificador, que traduce una secuencia de bytes en una secuencia de caracteres.A decoder, which translates a sequence of bytes into a sequence of characters.

La codificación de caracteres describe las reglas por las que funcionan un codificador y un descodificador.Character encoding describes the rules by which an encoder and a decoder operate. Por ejemplo, la clase UTF8Encoding describe las reglas para codificar y descodificar del Formato de transformación Unicode de 8 bits (UTF-8), que usa de uno a cuatro bytes para representar un único carácter 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. La codificación y la descodificación también pueden incluir validación.Encoding and decoding can also include validation. Por ejemplo, la clase UnicodeEncoding comprueba todos los suplentes para asegurarse de que constituyen pares suplentes válidos.For example, the UnicodeEncoding class checks all surrogates to make sure they constitute valid surrogate pairs. (Un par suplente consta de un carácter con un punto de código que va de U+D800 a U+DBFF, seguido de un carácter con un punto de código que va de U+DC00 a U+DFFF.) Una estrategia de reserva determina cómo trata un codificador los caracteres no válidos o cómo trata un descodificador los bytes no vá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.

Advertencia

Las clases de codificación de .NET proporcionan una manera de almacenar y convertir datos de caracteres..NET encoding classes provide a way to store and convert character data. No se deben usar para almacenar datos binarios en formato de cadena.They should not be used to store binary data in string form. Dependiendo de la codificación empleada, la conversión de datos binarios al formato de cadena con las clases de codificación puede presentar un comportamiento inesperado y mostrar datos inexactos o dañados.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 convertir datos binarios en un formato de cadena, use el método Convert.ToBase64String .To convert binary data to a string form, use the Convert.ToBase64String method.

.NET usa la codificación UTF-16 (representada por la clase UnicodeEncoding) para representar caracteres y cadenas..NET uses the UTF-16 encoding (represented by the UnicodeEncoding class) to represent characters and strings. Las aplicaciones cuyo destino es Common Language Runtime usan descodificadores para asignar representaciones de caracteres Unicode admitidas por Common Language Runtime a otros esquemas de codificación.Applications that target the common language runtime use encoders to map Unicode character representations supported by the common language runtime to other encoding schemes. Usan descodificadores para asignar caracteres de codificaciones no Unicode a Unicode.They use decoders to map characters from non-Unicode encodings to Unicode.

Este tema consta de las siguientes secciones:This topic consists of the following sections:

Codificaciones de .NETEncodings in .NET

Todas las clases de codificación de caracteres de .NET heredan de la clase System.Text.Encoding, que es una clase abstracta que define la funcionalidad común a todas las codificaciones 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 acceder a los objetos individuales de codificación implementados en .NET, haga lo siguiente:To access the individual encoding objects implemented in .NET, do the following:

  • Use las propiedades estáticas de la clase Encoding, que devuelven objetos que representan las codificaciones de caracteres estándar disponibles en .NET (ASCII, UTF-7, UTF-8, UTF-16 y 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 ejemplo, la propiedad Encoding.Unicode devuelve un objeto UnicodeEncoding :For example, the Encoding.Unicode property returns a UnicodeEncoding object. Cada objeto usa la reserva de reemplazo para controlar las cadenas que no puede codificar y los bytes que no puede descodificar.Each object uses replacement fallback to handle strings that it cannot encode and bytes that it cannot decode. (Para obtener más información, vea la sección Replacement Fallback ).(For more information, see the Replacement Fallback section.)

  • Llame al constructor de clase de la codificación.Call the encoding's class constructor. Se pueden crear instancias de los objetos para las codificaciones ASCII, UTF-7, UTF-8, UTF-16 y UTF-32 de esta manera.Objects for the ASCII, UTF-7, UTF-8, UTF-16, and UTF-32 encodings can be instantiated in this way. De forma predeterminada, cada objeto usa la reserva de reemplazo para controlar las cadenas que no puede codificar y los bytes que no puede descodificar, pero puede especificar que se debe producir una excepción en su lugar.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 obtener más información, vea las secciones Replacement Fallback y Exception Fallback ).(For more information, see the Replacement Fallback and Exception Fallback sections.)

  • Llame al constructor Encoding.Encoding(Int32) y pásele un entero que represente la codificación.Call the Encoding.Encoding(Int32) constructor and pass it an integer that represents the encoding. Los objetos de codificación estándar usan la reserva de reemplazo, y los objetos de codificación para la página de códigos y el juego de caracteres de doble byte (DBCS) usan el retroceso de ajuste perfecto para controlar las cadenas que no pueden codificar y los bytes que no pueden descodificar.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 obtener más información, vea la sección Best-Fit Fallback ).(For more information, see the Best-Fit Fallback section.)

  • Llame al método Encoding.GetEncoding, que devuelve cualquier estándar, página de códigos o codificación DBCS disponible en .NET.Call the Encoding.GetEncoding method, which returns any standard, code page, or DBCS encoding available in .NET. Las sobrecargas permiten especificar un objeto de reserva para el codificador y para el descodificador.Overloads let you specify a fallback object for both the encoder and the decoder.

Nota

El estándar Unicode asigna un punto de código (un número) y un nombre a cada carácter en todos los scripts admitidos.The Unicode Standard assigns a code point (a number) and a name to each character in every supported script. Por ejemplo, el carácter "A" está representado por el punto de código U+0041 y el nombre "LATIN CAPITAL LETTER A".For example, the character "A" is represented by the code point U+0041 and the name "LATIN CAPITAL LETTER A". Las codificaciones de Formato de transformación Unicode (UTF) definen formas de codificar ese punto de código en una secuencia de uno o más bytes.The Unicode Transformation Format (UTF) encodings define ways to encode that code point into a sequence of one or more bytes. Un esquema de codificación Unicode simplifica el desarrollo de aplicaciones de uso internacional porque permite que los caracteres de cualquier juego de caracteres estén representados en una única codificación.A Unicode encoding scheme simplifies world-ready application development because it allows characters from any character set to be represented in a single encoding. Los desarrolladores de aplicaciones ya no tienen que realizar el seguimiento del esquema de codificación empleado para producir caracteres para un idioma o un sistema de escritura concreto, y se pueden compartir los datos internacionalmente entre sistemas sin dañarlos.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.

.NET admite tres codificaciones definidas por el estándar Unicode: UTF-8, UTF-16 y UTF-32..NET supports three encodings defined by the Unicode standard: UTF-8, UTF-16, and UTF-32. Para obtener más información, vea el estándar Unicode en la página principal de Unicode.For more information, see The Unicode Standard at the Unicode home page.

Se puede recuperar información sobre todas las codificaciones disponibles en .NET llamando al método Encoding.GetEncodings.You can retrieve information about all the encodings available in .NET by calling the Encoding.GetEncodings method. .NET admite los sistemas de codificación de caracteres que se muestran en la tabla siguiente..NET supports the character encoding systems listed in the following table.

CodificaciónEncoding ClaseClass DescripciónDescription Ventajas y desventajasAdvantages/disadvantages
ASCIIASCII ASCIIEncoding Codifica un intervalo limitado de caracteres usando los siete bits inferiores de un byte.Encodes a limited range of characters by using the lower seven bits of a byte. Como esta codificación solo admite valores de caracteres de U+0000 a U+007F, en la mayoría de los casos no resulta suficiente para aplicaciones de uso internacional.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 los caracteres como secuencias de caracteres ASCII de 7 bits.Represents characters as sequences of 7-bit ASCII characters. Los caracteres Unicode no ASCII se representan con una secuencia de escape de caracteres ASCII.Non-ASCII Unicode characters are represented by an escape sequence of ASCII characters. UTF-7 admite protocolos como los protocolos de correo electrónico y de grupos de noticias.UTF-7 supports protocols such as email and newsgroup protocols. Sin embargo, la codificación UTF-7 no es particularmente segura ni sólida.However, UTF-7 is not particularly secure or robust. En algunos casos, cambiar un bit puede modificar radicalmente la interpretación de toda una cadena UTF-7.In some cases, changing one bit can radically alter the interpretation of an entire UTF-7 string. En otros casos, diferentes cadenas UTF-7 pueden codificar el mismo texto.In other cases, different UTF-7 strings can encode the same text. Para las secuencias que incluyen caracteres no ASCII, UTF-7 necesita más espacio que UTF-8, y la codificación y descodificación son más lentas.For sequences that include non-ASCII characters, UTF-7 requires more space than UTF-8, and encoding/decoding is slower. Por tanto, debe usar UTF-8 en lugar de UTF-7 si es posible.Consequently, you should use UTF-8 instead of UTF-7 if possible.
UTF-8UTF-8 UTF8Encoding Representa cada punto de código Unicode como una secuencia de uno a cuatro bytes.Represents each Unicode code point as a sequence of one to four bytes. UTF-8 admite tamaños de datos de 8 bits y funciona bien con muchos sistemas operativos existentes.UTF-8 supports 8-bit data sizes and works well with many existing operating systems. Para el intervalo ASCII de caracteres, UTF-8 es idéntico a la codificación ASCII y permite un conjunto mayor de caracteres.For the ASCII range of characters, UTF-8 is identical to ASCII encoding and allows a broader set of characters. Sin embargo, para los scripts de Chino-Japonés-Coreano (CJK), UTF-8 puede necesitar tres bytes para cada carácter y puede generar tamaños de datos mayores que 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. Tenga en cuenta que, algunas veces, la cantidad de datos ASCII, como las etiquetas HTML, justifica el mayor tamaño para el intervalo de 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 punto de código Unicode como una secuencia de uno o dos enteros de 16 bits.Represents each Unicode code point as a sequence of one or two 16-bit integers. La mayoría de los caracteres Unicode comunes solo necesitan un punto de código UTF-16, aunque los caracteres Unicode suplementarios (U+10000 y posteriores) necesitan dos puntos de código UTF-16 suplentes.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. Se admiten tanto el orden de bytes little-endian como el big-endian.Both little-endian and big-endian byte orders are supported. Common Language Runtime usa la codificación UTF-16 para representar valores de tipo Char y String , y el sistema operativo Windows la usa para representar valores de tipo 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 punto de código Unicode como un entero de 32 bits.Represents each Unicode code point as a 32-bit integer. Se admiten tanto el orden de bytes little-endian como el big-endian.Both little-endian and big-endian byte orders are supported. La codificación UTF-32 se usa cuando las aplicaciones desean evitar el comportamiento de punto de código suplente de la codificación UTF-16 en sistemas operativos para los que el espacio codificado es muy 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. Los glifos únicos representados en una pantalla aún se pueden codificar con más de un carácter UTF-32.Single glyphs rendered on a display can still be encoded with more than one UTF-32 character.
Codificaciones ANSI/ISOANSI/ISO encodings Proporciona compatibilidad con diversas páginas de códigos.Provides support for a variety of code pages. En los sistemas operativos Windows, las páginas de códigos se usan para admitir un idioma o un grupo de idiomas concreto.On Windows operating systems, code pages are used to support a specific language or group of languages. Para obtener una tabla que muestra las páginas de códigos admitidas por .NET, vea la clase Encoding.For a table that lists the code pages supported by .NET, see the Encoding class. Puede recuperar un objeto de codificación para una página de códigos determinada llamando al método Encoding.GetEncoding(Int32) .You can retrieve an encoding object for a particular code page by calling the Encoding.GetEncoding(Int32) method. Una página de códigos contiene 256 puntos de código y se basa en cero.A code page contains 256 code points and is zero-based. En la mayoría de las páginas de códigos, los puntos de código 0 a 127 representan el juego de caracteres ASCII y los puntos de código 128 a 255 difieren de forma significativa entre las páginas de códigos.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 ejemplo, la página de códigos 1252 proporciona los caracteres para los sistemas de escritura latinos, incluidos el inglés, el alemán y el francés.For example, code page 1252 provides the characters for Latin writing systems, including English, German, and French. Los últimos 128 puntos de código de la página de códigos 1252 contienen los caracteres de acento.The last 128 code points in code page 1252 contain the accent characters. La página de códigos 1253 proporciona códigos de caracteres necesarios en el sistema de escritura griego.Code page 1253 provides character codes that are required in the Greek writing system. Los últimos 128 puntos de código de la página de códigos 1253 contienen los caracteres griegos.The last 128 code points in code page 1253 contain the Greek characters. Como resultado, una aplicación que se basa en páginas de códigos ANSI no puede almacenar griego y alemán en la misma secuencia de texto a menos que incluya un identificador que indique la página de códigos a la que se hace referencia.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.
Codificaciones de juegos de caracteres de doble byte (DBCS)Double-byte character set (DBCS) encodings Admite idiomas que contienen más de 256 caracteres, como el chino, el japonés y el coreano.Supports languages, such as Chinese, Japanese, and Korean, that contain more than 256 characters. En un DBCS, un par de puntos de código (un byte doble) representa cada carácter.In a DBCS, a pair of code points (a double byte) represents each character. La propiedad Encoding.IsSingleByte devuelve false para las codificaciones DBCS.The Encoding.IsSingleByte property returns false for DBCS encodings. Puede recuperar un objeto de codificación para un DBCS determinado llamando al método Encoding.GetEncoding(Int32) .You can retrieve an encoding object for a particular DBCS by calling the Encoding.GetEncoding(Int32) method. En un DBCS, un par de puntos de código (un byte doble) representa cada carácter.In a DBCS, a pair of code points (a double byte) represents each character. Cuando una aplicación controla datos DBCS, el primer byte de un carácter DBCS (el byte inicial) se procesa junto con el byte final que le sigue inmediatamente.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. Puesto que un único par de puntos de código de doble byte puede representar caracteres diferentes dependiendo de la página de códigos, este esquema aún no permite la combinación de dos idioma, como el japonés y el chino, en el mismo flujo de datos.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.

Estas codificaciones permiten trabajar con caracteres Unicode, así como con codificaciones que son las más usadas en aplicaciones heredadas.These encodings enable you to work with Unicode characters as well as with encodings that are most commonly used in legacy applications. Además, puede crear una codificación personalizada definiendo una clase que se deriva de Encoding e invalidar sus miembros.In addition, you can create a custom encoding by defining a class that derives from Encoding and overriding its members.

Notas de la plataforma: Núcleo de .NET.NET CorePlatform Notes: Núcleo de .NET.NET Core

De forma predeterminada, Núcleo de .NET.NET Core no pone a disposición codificaciones de páginas de código que no sean la página de códigos 28591 y las codificaciones Unicode, como UTF-8 y UTF-16.By default, Núcleo de .NET.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. Sin embargo, puede agregar que las codificaciones de páginas de código que se encuentran en las aplicaciones estándar de Windows que tienen como destino .NET a la aplicación.However, you can add the code page encodings found in standard Windows apps that target .NET to your app. Para obtener información completa, consulte el tema CodePagesEncodingProvider .For complete information, see the CodePagesEncodingProvider topic.

Seleccionar una clase de codificaciónSelecting an Encoding Class

Si tiene la oportunidad de elegir la codificación que se usará en la aplicación, debe usar una codificación Unicode, preferiblemente UTF8Encoding o 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. (.NET también admite una tercera codificación Unicode, UTF32Encoding).(.NET also supports a third Unicode encoding, UTF32Encoding.)

Si piensa usar una codificación ASCII (ASCIIEncoding), elija UTF8Encoding en su lugar.If you are planning to use an ASCII encoding (ASCIIEncoding), choose UTF8Encoding instead. Las dos codificaciones son idénticas para el juego de caracteres ASCII, pero UTF8Encoding presenta las ventajas siguientes:The two encodings are identical for the ASCII character set, but UTF8Encoding has the following advantages:

  • Puede representar todos los caracteres Unicode, mientras que ASCIIEncoding solo admite los valores de caracteres Unicode entre U+0000 y U+007F.It can represent every Unicode character, whereas ASCIIEncoding supports only the Unicode character values between U+0000 and U+007F.

  • Proporciona detección de errores y una mayor seguridad.It provides error detection and better security.

  • Se ha mejorado en materia de velocidad y debe ser más rápida que cualquier otra codificación.It has been tuned to be as fast as possible and should be faster than any other encoding. Incluso cuando todo el contenido es ASCII, las operaciones realizadas con UTF8Encoding son más rápidas que las operaciones realizadas con ASCIIEncoding.Even for content that is entirely ASCII, operations performed with UTF8Encoding are faster than operations performed with ASCIIEncoding.

Debe considerar la posibilidad de usar ASCIIEncoding solo para las aplicaciones heredadas.You should consider using ASCIIEncoding only for legacy applications. Sin embargo, incluso para las aplicaciones heredadas, UTF8Encoding podría ser una opción mejor por las razones siguientes (suponiendo la configuración predeterminada):However, even for legacy applications, UTF8Encoding might be a better choice for the following reasons (assuming default settings):

  • Si la aplicación tiene contenido que no es estrictamente ASCII y lo codifica con ASCIIEncoding, cada carácter no ASCII se codifica como un signo de interrogación (?).If your application has content that is not strictly ASCII and encodes it with ASCIIEncoding, each non-ASCII character encodes as a question mark (?). Si la aplicación descodifica después estos datos, la información se pierde.If the application then decodes this data, the information is lost.

  • Si la aplicación tiene contenido que no es estrictamente ASCII y lo codifica con UTF8Encoding, el resultado parece ininteligible si se interpreta 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. Sin embargo, si la aplicación usa un descodificador UTF-8 para descodificar estos datos, los datos realizan una acción de ida y vuelta correctamente.However, if the application then uses a UTF-8 decoder to decode this data, the data performs a round trip successfully.

En una aplicación web, los caracteres enviados al cliente como respuesta a una solicitud web deben reflejar la codificación empleada en el cliente.In a web application, characters sent to the client in response to a web request should reflect the encoding used on the client. En la mayoría de los casos, debe establecer la propiedad HttpResponse.ContentEncoding en el valor devuelto por la propiedad HttpRequest.ContentEncoding para mostrar el texto en la codificación que el usuario 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.

Usar un objeto de codificaciónUsing an Encoding Object

Un codificador convierte una cadena de caracteres (normalmente, caracteres Unicode) en su equivalente numérico (bytes).An encoder converts a string of characters (most commonly, Unicode characters) to its numeric (byte) equivalent. Por ejemplo, podría usar un codificador ASCII para convertir caracteres Unicode en ASCII de forma que se puedan mostrar en la consola.For example, you might use an ASCII encoder to convert Unicode characters to ASCII so that they can be displayed at the console. Para realizar la conversión, se llama al método Encoding.GetBytes.To perform the conversion, you call the Encoding.GetBytes method. Si desea determinar cuántos bytes son necesarios para almacenar los caracteres codificados antes de realizar la codificación, puede llamar al 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.

En el ejemplo siguiente se usa una única matriz de bytes para codificar cadenas en dos operaciones independientes.The following example uses a single byte array to encode strings in two separate operations. Mantiene un índice que indica la posición inicial de la matriz de bytes para el siguiente conjunto de bytes codificados con ASCII.It maintains an index that indicates the starting position in the byte array for the next set of ASCII-encoded bytes. Llama al método ASCIIEncoding.GetByteCount(String) para asegurarse de que la matriz de bytes es suficiente para alojar la cadena codificada.It calls the ASCIIEncoding.GetByteCount(String) method to ensure that the byte array is large enough to accommodate the encoded string. A continuación, llama al método ASCIIEncoding.GetBytes(String, Int32, Int32, Byte[], Int32) para codificar los caracteres de la cadena.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.

Un descodificador convierte una matriz de bytes que refleja una codificación de caracteres determinada en un juego de caracteres, ya sea en una matriz de caracteres o en una cadena.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 descodificar una matriz de bytes en una matriz de caracteres, se llama al método Encoding.GetChars.To decode a byte array into a character array, you call the Encoding.GetChars method. Para descodificar una matriz de bytes en una cadena, se llama al método GetString .To decode a byte array into a string, you call the GetString method. Si desea determinar cuántos caracteres son necesarios para almacenar los bytes descodificados antes de realizar la descodificación, puede llamar al 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.

En el ejemplo siguiente se codifican tres cadenas y después se descodifican en una sola matriz de caracteres.The following example encodes three strings and then decodes them into a single array of characters. Se mantiene un índice que indica la posición inicial de la matriz de caracteres para el siguiente juego de caracteres descodificados.It maintains an index that indicates the starting position in the character array for the next set of decoded characters. Se llama al método GetCharCount para asegurarse de que la matriz de caracteres es suficientemente grande para alojar todos los caracteres descodificados.It calls the GetCharCount method to ensure that the character array is large enough to accommodate all the decoded characters. A continuación, se llama al método ASCIIEncoding.GetChars(Byte[], Int32, Int32, Char[], Int32) para descodificar la 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.

Los métodos de codificación y descodificación de una clase derivada de Encoding están diseñados para funcionar en un conjunto completo de datos; es decir, todos los datos que se va a codificar o descodificar se proporciona en una única llamada al 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. Sin embargo, en algunos casos, los datos están disponibles en una secuencia y los datos que se va a codificar o descodificar pueden estar disponibles solo desde operaciones de lectura independientes.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. Para ello, la operación de codificación o descodificación debe recordar cualquier estado guardado de su invocación anterior.This requires the encoding or decoding operation to remember any saved state from its previous invocation. Los métodos de clases derivadas de Encoder y Decoder pueden controlar las operaciones de codificación y descodificación que abarcan varias llamadas a métodos.Methods of classes derived from Encoder and Decoder are able to handle encoding and decoding operations that span multiple method calls.

Hay disponible un objeto Encoder para una codificación determinada desde la propiedad Encoding.GetEncoder de esa codificación.An Encoder object for a particular encoding is available from that encoding's Encoding.GetEncoder property. Hay disponible un objeto Decoder para una codificación determinada desde la propiedad Encoding.GetDecoder de esa codificación.A Decoder object for a particular encoding is available from that encoding's Encoding.GetDecoder property. Para las operaciones de descodificación, tenga en cuenta que las clases derivadas de Decoder incluyen un método Decoder.GetChars , pero no tienen un método que se corresponda con 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.

En el ejemplo siguiente se muestra la diferencia entre el uso de los métodos Encoding.GetChars y Decoder.GetChars para descodificar una 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. En el ejemplo se codifica una cadena que contiene algunos caracteres Unicode en un archivo y, a continuación, se usan los dos métodos de descodificación para descodificarlos de diez bytes en diez bytes.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. Puesto que hay un par suplente en los bytes décimo y undécimo, se descodifica en llamadas a métodos independientes.Because a surrogate pair occurs in the tenth and eleventh bytes, it is decoded in separate method calls. Como muestra el resultado, el método Encoding.GetChars no puede descodificar los bytes correctamente y, en su lugar, los reemplaza con U+FFFD (carácter de reemplazo).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 otra parte, el método Decoder.GetChars puede descodificar correctamente la matriz de bytes para obtener la cadena 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

Elegir una estrategia de reinterpretaciónChoosing a Fallback Strategy

Cuando un método intenta codificar o descodificar un carácter pero no existe ninguna asignación, debe implementar una estrategia de reserva que determine cómo se debe tratar la asignación incorrecta.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. Hay tres tipos de estrategias de reserva:There are three types of fallback strategies:

  • Best-Fit FallbackBest-fit fallback

  • Replacement FallbackReplacement fallback

  • Exception FallbackException fallback

Importante

Los problemas más frecuentes en las operaciones de codificación se producen cuando un carácter Unicode no se puede asignar a una codificación determinada de la página de códigos.The most common problems in encoding operations occur when a Unicode character cannot be mapped to a particular code page encoding. Los problemas más comunes de las operaciones de descodificación se producen cuando las secuencias no válidas de bytes no se pueden traducir a caracteres Unicode válidos.The most common problems in decoding operations occur when invalid byte sequences cannot be translated into valid Unicode characters. Por estas razones, debe saber qué estrategia de reserva emplea un determinado objeto de codificación.For these reasons, you should know which fallback strategy a particular encoding object uses. Siempre que sea posible, debe especificar la estrategia de reserva usada por un objeto de codificación cuando se crea una instancia del objeto.Whenever possible, you should specify the fallback strategy used by an encoding object when you instantiate the object.

Best-Fit FallbackBest-Fit Fallback

Cuando un carácter no tiene una coincidencia exacta en la codificación de destino, el codificador puede intentar asignarle a un carácter similar.When a character does not have an exact match in the target encoding, the encoder can try to map it to a similar character. (La reserva con ajuste perfecto es principalmente un problema de codificación en lugar de un problema de descodificación.(Best-fit fallback is mostly an encoding rather than a decoding issue. Hay muy pocas páginas de códigos que contengan caracteres que no se puedan asignar correctamente a Unicode.) La reserva con ajuste perfecto es el valor predeterminado para las codificaciones de páginas de códigos y de juegos de caracteres de doble byte recuperadas por las sobrecargas de Encoding.GetEncoding(Int32) y Encoding.GetEncoding(String).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.

Nota

En teoría, las clases de codificación Unicode proporcionadas en .NET (UTF8Encoding, UnicodeEncoding y UTF32Encoding) admiten cada carácter de todos los juegos de caracteres, por lo que se pueden usar para eliminar los problemas de reserva con ajuste perfecto.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.

Las estrategias de ajuste perfecto varían en páginas de códigos diferentes.Best-fit strategies vary for different code pages. Por ejemplo, para algunas páginas de códigos, los caracteres latinos de ancho completo se asignarán a caracteres latinos de ancho medio, que son más comunes.For example, for some code pages, full-width Latin characters map to the more common half-width Latin characters. Para otras páginas de códigos no se realiza esta asignación.For other code pages, this mapping is not made. Incluso con una estrategia de ajuste perfecto dinámica, algunos caracteres no tienen un ajuste imaginable en algunas codificaciones.Even under an aggressive best-fit strategy, there is no imaginable fit for some characters in some encodings. Por ejemplo, un ideograma chino no tiene ninguna asignación razonable a la página de códigos 1252.For example, a Chinese ideograph has no reasonable mapping to code page 1252. En este caso, se emplea una cadena de reemplazo.In this case, a replacement string is used. De forma predeterminada, esta cadena es simplemente un carácter QUESTION MARK (U+003F).By default, this string is just a single QUESTION MARK (U+003F).

Nota

Las estrategias de ajuste perfecto no están documentadas de forma detallada.Best-fit strategies are not documented in detail. Sin embargo, varias páginas de códigos se documentan en el sitio web de Unicode Consortium.However, several code pages are documented at the Unicode Consortium's website. Revise el archivo Léame.txt de esa carpeta para obtener una descripción de cómo interpretar los archivos de asignación.Please review the readme.txt file in that folder for a description of how to interpret the mapping files.

En el ejemplo siguiente se usa la página de códigos 1252 (la página de códigos de Windows para los idiomas de Europa occidental) para mostrar la asignación con ajuste perfecto y sus desventajas.The following example uses code page 1252 (the Windows code page for Western European languages) to illustrate best-fit mapping and its drawbacks. El método Encoding.GetEncoding(Int32) se usa para recuperar un objeto de codificación para la página de códigos 1252.The Encoding.GetEncoding(Int32) method is used to retrieve an encoding object for code page 1252. De forma predeterminada, usa una asignación con ajuste perfecto para los caracteres Unicode que no admite.By default, it uses a best-fit mapping for Unicode characters that it does not support. En el ejemplo se crea una instancia de una cadena que contiene tres caracteres no ASCII, CIRCLED LATIN CAPITAL LETTER S (U+24C8), SUPERSCRIPT FIVE (U+2075) e INFINITY (U+221E), separados por espacios en blanco.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 muestra el resultado del ejemplo, cuando se codifica la cadena, los tres caracteres originales que no son espacios en blanco se reemplazan con QUESTION MARK (U+003F), DIGIT FIVE (U+0035) y DIGIT EIGHT (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). DIGIT EIGHT es un reemplazo especialmente deficiente para el carácter INFINITY no compatible y QUESTION MARK indica que no había ninguna asignación disponible para el carácter 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

La asignación con ajuste perfecto es el comportamiento predeterminado para un objeto Encoding que codifica los datos Unicode en datos de página de códigos, y hay aplicaciones heredadas que se basan en este comportamiento.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. Sin embargo, la mayoría de las aplicaciones nuevas deben evitarlo por razones de seguridad.However, most new applications should avoid best-fit behavior for security reasons. Por ejemplo, las aplicaciones no deben asignar nombres de dominio mediante una codificación con ajuste perfecto.For example, applications should not put a domain name through a best-fit encoding.

Nota

También puede implementar una asignación personalizada de reserva con ajuste perfecto para una codificación.You can also implement a custom best-fit fallback mapping for an encoding. Para más información, vea la sección Implementing a Custom Fallback Strategy .For more information, see the Implementing a Custom Fallback Strategy section.

Si la reserva con ajuste perfecto es el valor predeterminado para un objeto de codificación, puede elegir otra estrategia de reserva cuando se recupera un objeto Encoding llamando a la sobrecarga de Encoding.GetEncoding(Int32, EncoderFallback, DecoderFallback) o 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. La próxima sección incluye un ejemplo que reemplaza con un asterisco (*) cada carácter que no se puede asignar a la página de códigos 1252.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

Replacement FallbackReplacement Fallback

Cuando un carácter no tiene una coincidencia exacta en el esquema de destino, pero no hay ningún carácter adecuado al que se pueda asignar, la aplicación puede especificar un carácter o una cadena de reemplazo.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. Este es el comportamiento predeterminado del descodificador Unicode, que reemplaza cualquier secuencia de dos bytes que no pueda descodificar con 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). También es el comportamiento predeterminado de la clase ASCIIEncoding , que reemplaza cada carácter que no puede codificar o descodificar con un signo de interrogación.It is also the default behavior of the ASCIIEncoding class, which replaces each character that it cannot encode or decode with a question mark. En el ejemplo siguiente se muestra el reemplazo de caracteres para la cadena Unicode del ejemplo anterior.The following example illustrates character replacement for the Unicode string from the previous example. Como muestra el resultado, cada carácter que no se puede descodificar en un valor de bytes ASCII se reemplaza con 0x3F, que es el código ASCII de un signo de interrogación.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

.NET incluye las clases EncoderReplacementFallback y DecoderReplacementFallback, que sustituyen una cadena de reemplazo si un carácter no se asigna exactamente en una operación de codificación o descodificación..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. De forma predeterminada, esta cadena de reemplazo es un signo de interrogación, pero puede llamar a una sobrecarga del constructor de clase para elegir otra cadena diferente.By default, this replacement string is a question mark, but you can call a class constructor overload to choose a different string. Normalmente, la cadena de reemplazo es un carácter único, aunque esto no es un requisito.Typically, the replacement string is a single character, although this is not a requirement. En el ejemplo siguiente se cambia el comportamiento del codificador de la página de códigos 1252 creando una instancia de un objeto EncoderReplacementFallback que usa un asterisco (*) como cadena de reemplazo.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

Nota

También puede implementar una clase de reemplazo para una codificación.You can also implement a replacement class for an encoding. Para más información, vea la sección Implementing a Custom Fallback Strategy .For more information, see the Implementing a Custom Fallback Strategy section.

Además de QUESTION MARK (U+003F), el REPLACEMENT CHARACTER de Unicode (U+FFFD) se suele usar como cadena de reemplazo, especialmente al descodificar secuencias de bytes que no se puede traducir correctamente a 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. Sin embargo, se puede elegir cualquier cadena de reemplazo y esta puede contener varios caracteres.However, you are free to choose any replacement string, and it can contain multiple characters.

Reserva de excepciónException Fallback

En lugar de proporcionar una reserva con ajuste perfecto o una cadena de reemplazo, un codificador puede producir EncoderFallbackException si no puede codificar un juego de caracteres y un descodificador puede producir DecoderFallbackException si no puede descodificar una 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 producir una excepción en operaciones de codificación y descodificación, se proporciona un objeto EncoderExceptionFallback y un objeto DecoderExceptionFallback, respectivamente, al 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. En el ejemplo siguiente se muestra la reserva de excepción con la clase 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.

Nota

También puede implementar un controlador de excepciones personalizado para una operación de codificación.You can also implement a custom exception handler for an encoding operation. Para más información, vea la sección Implementing a Custom Fallback Strategy .For more information, see the Implementing a Custom Fallback Strategy section.

Los objetos EncoderFallbackException y DecoderFallbackException proporcionan la siguiente información acerca de la condición que provocó la excepción:The EncoderFallbackException and DecoderFallbackException objects provide the following information about the condition that caused the exception:

Aunque los objetos EncoderFallbackException y DecoderFallbackException proporcionan información suficiente de diagnóstico sobre la excepción, no proporcionan acceso al búfer de codificación o descodificación.Although the EncoderFallbackException and DecoderFallbackException objects provide adequate diagnostic information about the exception, they do not provide access to the encoding or decoding buffer. Por tanto, no permiten reemplazar o corregir datos no válidos dentro del método de codificación o descodificación.Therefore, they do not allow invalid data to be replaced or corrected within the encoding or decoding method.

Implementar una estrategia de reserva personalizadaImplementing a Custom Fallback Strategy

Además de la asignación con ajuste perfecto implementada internamente por las páginas de códigos, .NET incluye las siguientes clases para implementar una estrategia de reserva:In addition to the best-fit mapping that is implemented internally by code pages, .NET includes the following classes for implementing a fallback strategy:

Además, puede implementar una solución personalizada que use reserva con ajuste perfecto, reserva de reemplazo o reserva de excepción siguiendo estos pasos:In addition, you can implement a custom solution that uses best-fit fallback, replacement fallback, or exception fallback, by following these steps:

  1. Derive una clase de EncoderFallback para las operaciones de codificación y de DecoderFallback para las operaciones de descodificación.Derive a class from EncoderFallback for encoding operations, and from DecoderFallback for decoding operations.

  2. Derive una clase de EncoderFallbackBuffer para las operaciones de codificación y de DecoderFallbackBuffer para las operaciones de descodificación.Derive a class from EncoderFallbackBuffer for encoding operations, and from DecoderFallbackBuffer for decoding operations.

  3. Para la reserva de excepción, si las clases EncoderFallbackException y DecoderFallbackException predefinidas no satisfacen sus necesidades, derive una clase de un objeto de excepción como Exception o 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.

Derivar de EncoderFallback o DecoderFallbackDeriving from EncoderFallback or DecoderFallback

Para implementar una solución de reserva personalizada, debe crear una clase que herede de EncoderFallback para las operaciones de codificación y de DecoderFallback para las operaciones de descodificación.To implement a custom fallback solution, you must create a class that inherits from EncoderFallback for encoding operations, and from DecoderFallback for decoding operations. Las instancias de estas clases se pasan al método Encoding.GetEncoding(String, EncoderFallback, DecoderFallback) y actúan como intermediario entre la clase de codificación y la implementación de reserva.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.

Cuando se crea una solución de reserva personalizada para un codificador o un descodificador, debe implementar los miembros siguientes:When you create a custom fallback solution for an encoder or decoder, you must implement the following members:

Derivar de EncoderFallbackBuffer o DecoderFallbackBufferDeriving from EncoderFallbackBuffer or DecoderFallbackBuffer

Para implementar una solución de reserva personalizada, debe crear también una clase que herede de EncoderFallbackBuffer para las operaciones de codificación y de DecoderFallbackBuffer para las operaciones de descodificación.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. El método CreateFallbackBuffer de las clases EncoderFallback y DecoderFallback devuelve instancias de estas clases.Instances of these classes are returned by the CreateFallbackBuffer method of the EncoderFallback and DecoderFallback classes. El codificador llama al método EncoderFallback.CreateFallbackBuffer cuando encuentra el primer carácter que no puede codificar y el descodificador llama al método DecoderFallback.CreateFallbackBuffer cuando encuentra uno o más bytes que no puede descodificar.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. Las clases EncoderFallbackBuffer y DecoderFallbackBuffer proporcionan la implementación de reserva.The EncoderFallbackBuffer and DecoderFallbackBuffer classes provide the fallback implementation. Cada instancia representa un búfer que contiene los caracteres de reserva que reemplazarán el carácter que no se puede codificar o la secuencia de bytes que no se puede descodificar.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.

Cuando se crea una solución de reserva personalizada para un codificador o un descodificador, debe implementar los miembros siguientes:When you create a custom fallback solution for an encoder or decoder, you must implement the following members:

Si la implementación de reserva es una reserva con ajuste perfecto o una reserva de reemplazo, las clases derivadas de EncoderFallbackBuffer y DecoderFallbackBuffer también mantienen dos campos de instancia privados: el número exacto de caracteres del búfer y el índice del carácter siguiente del búfer que se va a devolver.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.

Ejemplo de EncoderFallbackAn EncoderFallback Example

En un ejemplo anterior se usaba la reserva de reemplazo para reemplazar caracteres Unicode que no correspondían a caracteres ASCII con un asterisco (*).An earlier example used replacement fallback to replace Unicode characters that did not correspond to ASCII characters with an asterisk (*). En el ejemplo siguiente se usa una implementación personalizada de reserva con ajuste perfecto en su lugar para proporcionar una mejor asignación de caracteres no ASCII.The following example uses a custom best-fit fallback implementation instead to provide a better mapping of non-ASCII characters.

En el código siguiente se define una clase denominada CustomMapper que se deriva de EncoderFallback para controlar la asignación con ajuste perfecto de caracteres no ASCII.The following code defines a class named CustomMapper that is derived from EncoderFallback to handle the best-fit mapping of non-ASCII characters. Su método CreateFallbackBuffer devuelve un objeto CustomMapperFallbackBuffer , que proporciona la implementación de EncoderFallbackBuffer .Its CreateFallbackBuffer method returns a CustomMapperFallbackBuffer object, which provides the EncoderFallbackBuffer implementation. La clase CustomMapper usa un objeto Dictionary<TKey,TValue> para almacenar las asignaciones de caracteres Unicode no compatibles (el valor de clave) y sus caracteres de 8 bits correspondientes (que se almacenan en dos bytes consecutivos en un entero 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 que esta asignación esté disponible para el búfer de reserva, la instancia de CustomMapper se pasa como un parámetro al constructor de clase CustomMapperFallbackBuffer.To make this mapping available to the fallback buffer, the CustomMapper instance is passed as a parameter to the CustomMapperFallbackBuffer class constructor. Puesto que la asignación más larga es la cadena "INF" por el carácter Unicode U+221E, la propiedad MaxCharCount devuelve 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

En el código siguiente se define la clase CustomMapperFallbackBuffer , que se deriva de EncoderFallbackBuffer.The following code defines the CustomMapperFallbackBuffer class, which is derived from EncoderFallbackBuffer. El diccionario que contiene las asignaciones con ajuste perfecto y que se define en la instancia de CustomMapper está disponible desde su constructor de clase.The dictionary that contains best-fit mappings and that is defined in the CustomMapper instance is available from its class constructor. Su método Fallback devuelve true si cualquiera de los caracteres Unicode que el codificador ASCII no puede codificar se definen en el diccionario de asignación; de lo contrario, devuelve 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 reserva, la variable count privada indica el número de caracteres que quedan por devolver y la variable index privada indica la posición en el búfer de cadena, charsToReturn, del siguiente carácter que se va a devolver.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

En el código siguiente se crean instancias del objeto CustomMapper y se pasa una instancia del mismo al 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. El resultado indica que la implementación de reserva con ajuste perfecto controla correctamente los tres caracteres no ASCII de la cadena 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

Vea tambiénSee also