1

I need to create a file where some parts are strings (utf-8), while some parts are bytes.

I tinkered for hours with StreamWriter and BinaryWriter, but this is the only thing that works:

        using (var stream = new FileStream(_caminho, FileMode.Create, FileAccess.Write))
        {
            using (var writer = new StreamWriter(stream))
            {
                writer.Write(myString);
            }   
        }
        using (var stream = new FileStream(_caminho, FileMode.Append, FileAccess.Write))
        {
            using (var writer = new BinaryWriter(stream))
            {
                writer.Write(oneSingleByte);
            }
        }

The problem is that I have to close the FileStream and open another one just to write a single byte, because either the BinaryStream.Write(string) method prepends a "length" field (undesired in my case) or the StreamWriter.Write(byte) encodes the byte value instead of actually writing directly.

My question is: is there another class I can use so that I can create the FileStream only once, and write my string and my byte one after another?

5
  • 2
    Why don't you convert you strings to byte arrays and write them with binary writer, too? Commented Apr 7, 2015 at 21:24
  • Why not write your string as bytes (or bytes as a string, if you prefer)? Commented Apr 7, 2015 at 21:24
  • 1
    Side note: I'd recommend to reconsider "don't want length-prefixed strings" requirement - reading is so much easier if you know length in advance. Commented Apr 7, 2015 at 21:26
  • As to "why I didn't" converted the string to array: of course because I didn't realized that! I solved the problem with binaryWriter.Write(myString.ToCharArray()); or alternatively binaryWriter.Write(Encoding.UTF8.GetBytes(myString)). Commented Apr 7, 2015 at 21:30
  • You probably want to use System.Text.Encoding as CodeCaster suggested below. Commented Apr 7, 2015 at 21:33

1 Answer 1

7

BinaryWriter prefixes written data so BinaryReader can read it. Without those prefixes, you must know exactly what you're doing when writing and reading the file.

You can omit both writers and directly write into the file if that's what you want:

using (var stream = new FileStream(_caminho, FileMode.Append, FileAccess.Write))
{
    stream.WriteByte('0'); 
    WriteString(stream, "foo", Encoding.UTF8);
}

private void WriteString(Stream stream, string stringToWrite, Encoding encoding)
{
    var charBuffer = encoding.GetBytes(stringToWrite);
    stream.Write(charBuffer, 0, charBuffer.Length);
}

You'll need to explicitly specify the encoding to get the bytes in, as String.ToByteArray returns the string as Unicode characters, which is .NET language for "UTF-16LE", giving you two bytes per character.

Sign up to request clarification or add additional context in comments.

2 Comments

Wouldn't FileStream.Write() need aditional parameters, like position and array size?
@CodeCaster The perfect answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.