Writing String to Stream and reading it back does not work

后端 未结 5 1069
死守一世寂寞
死守一世寂寞 2020-12-30 18:54

I want to write a String to a Stream (a MemoryStream in this case) and read the bytes one by one.

stringAsStream = new MemoryStream();
UnicodeEncoding uniEn         


        
相关标签:
5条回答
  • 2020-12-30 19:31

    Try this "one-liner" from Delta's Blog, String To MemoryStream (C#).

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

    The string will be loaded into the MemoryStream, and you can read from it. See Encoding.GetBytes(...), which has also been implemented for a few other encodings.

    0 讨论(0)
  • 2020-12-30 19:37

    After you write to the MemoryStream and before you read it back, you need to Seek back to the beginning of the MemoryStream so you're not reading from the end.

    UPDATE

    After seeing your update, I think there's a more reliable way to build the stream:

    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();
        }
    }
    

    As you can see, this code uses a StreamWriter to write the entire string (with proper encoding) out to the MemoryStream. This takes the hassle out of ensuring the entire byte array for the string is written.

    Update: I stepped into issue with empty stream several time. It's enough to call Flush right after you've finished writing.

    0 讨论(0)
  • 2020-12-30 19:39

    I think it would be a lot more productive to use a TextWriter, in this case a StreamWriter to write to the MemoryStream. After that, as other have said, you need to "rewind" the MemoryStream using something like 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
    

    Note that:

    StreamWriter defaults to using an instance of UTF8Encoding unless specified otherwise. This instance of UTF8Encoding is constructed without a byte order mark (BOM)

    Also, you don't have to create a new UnicodeEncoding() usually, since there's already one as a static member of the class for you to use in convenient utf-8, utf-16, and utf-32 flavors.

    And then, finally (as others have said) you're trying to convert the bytes directly to chars, which they are not. If I had a memory stream and knew it was a string, I'd use a TextReader to get the string back from the bytes. It seems "dangerous" to me to mess around with the raw bytes.

    0 讨论(0)
  • 2020-12-30 19:47

    You need to reset the stream to the beginning:

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

    This can also be done by setting the Position property to 0:

    stringAsStream.Position = 0
    
    0 讨论(0)
  • 2020-12-30 19:54

    You're using message.Length which returns the number of characters in the string, but you should be using the nubmer of bytes to read. You should use something like:

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

    You're then reading a single byte and expecting to get a character from it just by casting to char. UnicodeEncoding will use two bytes per character.

    As Justin says you're also not seeking back to the beginning of the stream.

    Basically I'm afraid pretty much everything is wrong here. Please give us the bigger picture and we can help you work out what you should really be doing. Using a StreamWriter to write and then a StreamReader to read is quite possibly what you want, but we can't really tell from just the brief bit of code you've shown.

    0 讨论(0)
提交回复
热议问题