La escritura de Cadena para transmitir y leerlo de nuevo no funciona

Quiero escribir una Cadena a una Secuencia (un MemoryStream en este caso) y leer los bytes uno por uno.

stringAsStream = new MemoryStream();
UnicodeEncoding uniEncoding = new UnicodeEncoding();
String message = "Message";

stringAsStream.Write(uniEncoding.GetBytes(message), 0, message.Length);

Console.WriteLine("This:\t\t" + (char)uniEncoding.GetBytes(message)[0]);
Console.WriteLine("Differs from:\t" + (char)stringAsStream.ReadByte());

La (no deseado) resultado que se obtiene es:

This:         M
Differs from: ?

Se se ve como que no se lee correctamente, como el primer carácter de «Mensaje» es ‘M’, que funciona cuando se obtienen los bytes de la UnicodeEncoding instancia, pero no cuando la lectura de vuelta de la secuencia.

¿Qué estoy haciendo mal?


La imagen más grande: tengo un algoritmo que funciona en los bytes de un Arroyo, me gustaría ser tan general como sea posible y trabajar con cualquier Secuencia. Me gustaría convertir ASCII Cadena en un MemoryStream, o tal vez de usar otro método para poder trabajar en la Cadena como un Arroyo. El algoritmo en cuestión de trabajo en los bytes de la Secuencia.

  • ¿Quieres leer los bytes o caracteres uno por uno, desde el arroyo? Tenga en cuenta que el byte != char como su codificación Unicode.
  • Sí, yo no. Y el byte será char como voy a ser de lectura ASCII de los documentos. Sería mejor utilizar algo distinto de uniEncoding en mi caso?
  • He añadido una imagen más grande, como se solicitó.
  • He actualizado mi respuesta con un ejemplo de código que podría funcionar mejor para usted.
  • Gracias a todos por su ayuda! Y lo siento por no incluir la imagen en grande desde el principio, ya que es necesario en este caso. Todas las respuestas que proporcione valor, por lo que todos dieron un voto de mí, al menos. 🙂
InformationsquelleAutor Deleted | 2010-04-13

5 Kommentare

  1. 64

    Después de escribir en el MemoryStream y antes de leerlo de nuevo, usted necesita para Seek de vuelta al principio de la MemoryStream de modo que no la lectura de la final.

    ACTUALIZACIÓN

    Después de ver su actualización, creo que hay una manera más confiable para construir la secuencia:

    UnicodeEncoding uniEncoding = new UnicodeEncoding();
    String message = "Message";
    
    //You might not want to use the outer using statement that I have
    //I wasn't sure how long you would need the MemoryStream object    
    using(MemoryStream ms = new MemoryStream())
    {
        var sw = new StreamWriter(ms, uniEncoding);
        try
        {
            sw.Write(message);
            sw.Flush();//otherwise you are risking empty stream
            ms.Seek(0, SeekOrigin.Begin);
    
            //Test and work with the stream here. 
            //If you need to start back at the beginning, be sure to Seek again.
        }
        finally
        {
            sw.Dispose();
        }
    }

    Como se puede ver, este código se utiliza un StreamWriter para escribir toda la cadena (con codificación correcta) a la MemoryStream. Esto se toma la molestia de garantizar la totalidad de la matriz de bytes para la cadena está escrito.

    Actualización: entré en el problema con la secuencia vacía varias veces. Es suficiente para llamar Ras a la derecha después de que usted haya terminado de escribir.

    • Que código de error en ms.Seek(0, SeekOrigin.Begin), porque poniendo un uso en StreamWriter cerrará su corriente, que en este caso es el MemoryStream. A continuación, cuando se intenta buscar, se le dará una Cannot access a closed Stream excepción.
    • Usted puede usar este método si ajusta la corriente en una clase de la que se anula la disposición de la secuencia subyacente. Esta respuesta a una pregunta relacionada con los puntos a una aplicación.
    • Como se señaló, este código no compila. La respuesta de Joel Purra es de una sola línea y funciona mucho mejor.
  2. 36

    Probar este «one-liner» de Delta del Blog, Cadena De MemoryStream (C#).

    MemoryStream stringInMemoryStream =
       new MemoryStream(ASCIIEncoding.Default.GetBytes("Your string here"));

    La cadena será cargado en la MemoryStream, y se puede leer de ella. Ver De la codificación.GetBytes(…), que también ha sido implementado por un par de otras codificaciones.

    • Y para obtener los datos de nuevo, Encoding.ASCII.GetString(ms.ToArray());.
    • Insto encarecidamente a cualquier persona que utilice este ejemplo para el uso de la Codificación.UTF8 sobre ASCII o cualquier otro más amplio ámbito de la codificación. Hay buenas posibilidades de cualquier texto escrito por los no-{americano, inglés, …} la gente de rendir mal en ASCII.
  3. 16

    Estás usando message.Length que devuelve el número de personajes en la cadena, pero usted debe estar utilizando el número de bytes a leer. Usted debe usar algo como:

    byte[] messageBytes = uniEncoding.GetBytes(message);
    stringAsStream.Write(messageBytes, 0, messageBytes.Length);

    Estás, a continuación, leer una sola byte y esperando para obtener un personaje de los que sólo mediante la conversión a char. UnicodeEncoding se utilizan dos bytes por carácter.

    Como Justin dice que eres también no buscando de nuevo al principio de la secuencia.

    Básicamente, me temo que casi todo lo que está mal aquí. Por favor, nos dan la imagen más grande y nos puede ayudar a trabajar de lo que debe realmente estar haciendo. El uso de un StreamWriter a escribir y, a continuación, un StreamReader a leer es, posiblemente, lo que quieran, pero nosotros realmente no puede decir que a partir de sólo una breve bits de código que has mostrado.

    • Después de escribir en un MemoryStream, no están obligados a Buscar el principio para empezar a leer de nuevo?
    • Sí, ese es otro problema 🙂
    • He añadido una imagen más grande, como se solicitó. Tal vez es más fácil entender lo que quiero hacer ahora.
  4. 5

    Creo que sería mucho más productivo utilizar un TextWriter, en este caso un StreamWriter para escribir en el MemoryStream. Después de que, como otros han dicho, usted necesita para «rebobinar» la MemoryStream el uso de algo como stringAsStream.Position = 0L;.

    stringAsStream = new MemoryStream();
    
    //create stream writer with UTF-16 (Unicode) encoding to write to the memory stream
    using(StreamWriter sWriter = new StreamWriter(stringAsStream, UnicodeEncoding.Unicode))
    {
      sWriter.Write("Lorem ipsum.");
    }
    stringAsStream.Position = 0L; //rewind

    Tenga en cuenta que:

    StreamWriter valores predeterminados para el uso de una instancia de UTF8Encoding a menos que se especifique lo contrario. Esta instancia de UTF8Encoding se construye sin una marca de orden de bytes (BOM)

    También, usted no tiene que crear un new UnicodeEncoding() generalmente, puesto que ya existe uno como un miembro estático de la clase para que los utilice en conveniente utf-8, utf-16 y utf-32 sabores.

    Y, por último, (como otros han dicho) usted está tratando de convertir la bytes directamente a chars, que no lo son. Si yo tuviera una secuencia de memoria y sabía que era una cadena, yo uso un TextReader para obtener la cadena de bytes. Parece «peligroso» para mí, el lío con la cruda bytes.

    • Mi objetivo principal es trabajar con Secuencias. Como voy a estar trabajando en los bytes de texto ASCII y archivos binarios.
    • Ah, ya veo. En ese caso, supongo que te tiene que meterse con ellos bytes. 😉
    • Una cosa en la rebobinar parte, tengo Cannot access a closed Stream.
  5. 1

    Que usted necesita para restablecer la secuencia de inicio:

    stringAsStream.Seek(0, SeekOrigin.Begin);
    Console.WriteLine("Differs from:\t" + (char)stringAsStream.ReadByte());

    Esto también se puede hacer mediante el ajuste de la Position propiedad a 0:

    stringAsStream.Position = 0

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea