what’s the difference between a streamwriter and a binarywriter?

what’s the difference between a streamwriter and a binarywriter?

this really confuses me, say i want to save an integer into a file, int x=56, the binarywriter takes the ascii equivalent of the representation of 56 in memory 
00000000 00000000 00000000 00111000 , which would be  : null null null 8 and write it to the file? am i correct? can someone explain how those twofunction and when should i use each of them? im using c# btw. thanx in advance!

Solutions/Answers:

Answer 1:

From the MSDN pages for StreamWriter and BinaryWriter you can clearly see the differences:

StreamWriter:

Implements a TextWriter for writing
characters to a stream in a particular
encoding.

And:

BinaryWriter:

Writes primitive types in binary to a
stream and supports writing strings in
a specific encoding.

The first one writes things as text, the second writes in binary, little endian, so int x = 56 would be written 00111000 00000000 00000000 00000000.

Answer 2:

The binary writer writes the in-memory binary representation of the integer. The stream writer writes the ASCII representation. Generally speaking, the former can be more compact and efficient (consider writing the integer 23861398 – the binary writer would require 4 bytes, but the stream writer would require 8, 16, or even 32 depending on the encoding) but the latter results in plain old text.

Answer 3:

From what I can discern… StreamWriter is more for text and BinaryWriter is for primitive types including strings of particular encodings. Saying that the BinaryWriter writes in binary though is kind of misleading to people who take things at face value… as I did. I assumed that when I write an integer to the underlying stream it would actually write it in binary and I could read it again as a stream of 1’s and 0’s.
To put things down as it looks in code:

MemoryStream stream = new MemoryStream(); 

BinaryWriter bw = new BinaryWriter(stream);

bw.Write(35);

// is equivalent to doing:

stream.Write(BitConverter.GetBytes((int)35), 0, 4);

Though the BinaryWriter uses bit shifting to extract the bytes and BitConverter uses unsafe pointer casting, the result is the same. An int is 32 bits or 4 bytes in length, and all it simply does is writes the bytes that represent that int to it’s underlying stream.

StreamWriter does the same thing only that it’s meant for text, so integers won’t be converted to bytes, but instead to chars… this is similar to writing:

byte[] buffer = Encoding.UTF8.GetBytes("my string here 1234");
stream.Write(buffer, 0, buffer.Length);

That is why I said it’s misleading to say it writes in binary.. because it does.. technically. Break down each written byte into bits and you get the binary values. However it would make more sense to say that it writes primitive types as byte arrays. If you were to convert the stream to a string you would not get a string of 1’s and 0’s.

Answer 4:

StreamWriter is for text and BinaryWriter writes the actual binary representation of what you want to write. I’m not 100 % sure, but almost :).

Our Awesome Tools

References

ref for variables not parameters in functions

ref for variables not parameters in functions

Suppose I have a Person class and have the following:
Person A = new Person("Tom");
Person B = A;

Is there a way I can change it so that if I assign a new Person to B, B = new Person("Harry"), A would be referring to the same instance too?  I know you can do that in a ref parameter assignment in a function.

Solutions/Answers:

Answer 1:

UPDATE: The feature described here was added to C# 7.


The feature you want is called “ref locals” and it is not supported in C#.

The CLR does support generating code that contains ref locals, and a few years ago I wrote an experimental version of C# that had the feature you want, just to see if it would work. You could do something like:

Person a = whatever;
ref Person b = ref a;

and then as you say, changes to “b” would change the contents of “a”. The two variables become aliases for the same storage location.

Though it was a nice little feature and worked well, we decided to not take it for C#. It’s possible that it could still happen in a hypothetical future version of the language, but I would not get all excited about it in expectation; it will probably not happen.

(Remember, all of Eric’s musings about hypothetical future versions of any Microsoft product are For Entertainment Purposes Only.)

Answer 2:

No it isn’t possible in safe code(beyond ref function parameters). In unsafe code you might be able to use pointers to achieve that, but I don’t think that’s a good idea.

A contains the reference to “Tom” as a value. You’d need a reference to A to change where it points.

If we consider similar code in a language which explicitly uses pointers instead of implicitly treating instances of classes as references:

Person* A=new Person("Tom");
Person* B=A;
B=new Person("Harry");//Changes only B
Person** C=&A;
(*C)=new Person("John");//Now A changes

So you need a pointer to a pointer in order to change A. If you transfer this to C# you’d need a reference to a local variable. And those are only available in the form of ref function parameters. This avoids some lifetime issues since a reference to a local variable can’t safely outlive that local variable.

If these are not private variables you could make B a property that modifies A in the setter.

Person B{get{return A;} set{A=value;}}

Answer 3:

There is no direct way to do that.

You can either take a source-code approach like:

A = B = new Person("Harry")

Or use a generic type. Something like:

var A = new ReferenceHolder<Person> (new Person("Tom")); 
var B = A;

In C# you could also use a pointer (so basically a ref type) but that approach is not statically verifyable and not suggested.

Our Awesome Tools

References