I notice that nobody has answered the actual questions.
Is something lost when reading data into a string?
A JPEG file contains a picture rather than words. This bicture has a binary representation as a sequence of bytes. Some of those bytes have the value 0x00 also represented as NUL. In a string, a byte containing with this value is interpreted as marking the end of string. Data past the end of string is treated as unused buffer and is ignored.
When you write the string out to a file, nothing past the first NUL is included. As a result, the file is not a complete binary image and is rejected by the validation logic of software trying to interpret it as a JPEG.
So data generally is lost when you load a string with non-textual data. The problem here is that you have effectively made an invalid typecast, but neither compiler nor the runtime has stopped you, and the result is data corruption.
What is it really good for?
Several thing. As others have said, strings are designed to contain text. In .NET, strings support encodings other than plain old ASCII. There is also extensive support for text manipulation. Look up format specifiers in help for a spectacular example of string manipulation.
Why do C# strings use NUL for end of string?
This is a legacy thing. NUL isn't much good for anything else and doing so simplifies marshalling strings in and out of managed code. BSTR does the same thing for the same reasons.