Write and read data to the MemoryStream [duplicate] - c#

This question already has answers here:
Can't create MemoryStream
(2 answers)
FileResult with MemoryStream gives empty result .. what's the problem?
(2 answers)
Closed 1 year ago.
I am try to write some data to the MemoryStream, and then correctly read it. For example :
int someValue = 10;
Console.WriteLine(someValue);
Console.ReadKey();
MemoryStream lMemoryStream = new MemoryStream();
StreamWriter lStreamWriter = new StreamWriter(lMemoryStream);
lStreamWriter.Write(someValue);
StreamReader lStreamReader = new StreamReader(lMemoryStream);
int someValue2 = lStreamReader.Read();
Console.WriteLine(someValue2);
Console.ReadKey();
But in response I get empty memoryStream, and get value -1. What's wrong?

You forgot to flush your data into the stream. You also have to set the position to 0 if you want to read data from the beginning.
lStreamWriter.Flush(); // after .Write!
lMemoryStream.Position = 0; // before read!
Tip: Don't close the writer, it will also close the MemoryStream. Close it after you're done with the data.

When you write to stream, you advance your position (in said stream). To read the value you've just written you have to "rewind" your position (by setting it).

Related

int.TryParse returning false on the first line of data from StreamReader

Long time reader, first time poster.
I'm simply reading numbers from a text file to into an integer array, one integer per line, using the StreamReader class. I read through the file once to get the number of lines so I can properly define the destination array. I then reset the pointer to the beginning of the text file and read again, this time using int.TryParse covert the strings to integers and write to the array. But the first line from the file returns 'false' from the TryParse - even though the string is merely '3. The subsequent lines return 'true' just fine. Here's the snippet ...
_NumbersInMemory = new int[lineCount];
theFileStream.DiscardBufferedData();
theFileStream.BaseStream.Seek(0, 0);
lineCount = 0;
do
{
string theLineFromTheFle = theFileStream.ReadLine();
int numberInMemoryTemporarily = 0;
bool result = int.TryParse(theLineFromTheFle, out numberInMemoryTemporarily);
if (result)
{
_NumbersInMemory[lineCount] = numberInMemoryTemporarily;
}
lineCount++;
} while (!theFileStream.EndOfStream);
theStream.Close();
Is the reset to the beginning of the file (which is only 82 lines) messing-up the input to the first iteration of TryParse, or something like that?
I would consider using this code instead:
_NumbersInMemory =
File
.ReadAllLines(#"path")
.Select(line => line.Trim())
.Select(line =>
{
int numberInMemoryTemporarily = 0;
if (int.TryParse(line, out numberInMemoryTemporarily))
{
return numberInMemoryTemporarily;
}
return 0;
})
.ToArray();
The .Select(line => line.Trim()) may be enough to get rid of the problem you have.
Your file probably has UTF8 or Unicode byte-order-marks (BOM) at the start of the file. Looking at the file in a hex-viewer can verify this.
When you first open the file, the StreamReader class reads these bytes to determine the proper encoding of the rest of the file. The first ReadLine() will not include these bytes.
By seeking to byte 0 of the underlying stream, the next ReadLine() will include these bytes because the StreamReader does not know it should skip them (it's already read and processed them).
Either read the file once by using ReadAllLines, or close and re-open the file to start reading again rather than seeking back to the beginning.

Clean alternatives to passing index by reference

In my code I am parsing an array of bytes. To sequentially parse the bytes I am currently passing around the index like so:
headerData = ParseHeader(bytes, ref index)
middleData = ParseMiddle(bytes, ref index)
tailData = ParseTail (bytes, ref index)
Without hardcoding the amount to increment the header, is there a way to achieve similar functionality without having to pass the index by reference? Is this one of the rare cases that using the ref keyword is the best solution?
Like SLaks said, a possible solution is to use a stream.
To create a stream from your current bytes array you can do the following:
MemoryStream stream = new MemoryStream(bytes);
To read the current byte of the stream you can use the ReadByte method, shown below:
byte b = stream.ReadByte();
The stream will keep track of the current index in the array, so your new code would look like:
MemoryStream stream = new MemoryStream(bytes);
headerData = ParseHeader(stream)
middleData = ParseMiddle(stream)
tailData = ParseTail (stream)
Check out the documentation to see other methods that are available for MemoryStream.

object returned from webservice call gets mangle with additional bytes in my conversion function

Concise...object returned from webservice call gets mangle with additional bytes in my conversion function.
Basically I have a webreference that I send an XDocument to
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
Byte[] baXml = encoding.GetBytes(xdoc.ToString());
object o = MEF_Test.NewSubmission("*********", "*********", baXml);
The transmission is successful and I get back what I assume is the xml document and I am trying to go back to an XDocument. I convert my object to a byte array
Byte[] baResponse = ObjectToByteArray(o);
I put this function in at the bottom but it may be where there error is at
The object I get back is 10492 characters but gets bigger by 28 bytes to the size of 10520 after conversion
string ss = Encoding.UTF8.GetString(baResponse);
string ss1 = ss.Substring(28);
XDocument xSubmissionResponse = XDocument.Parse(ss1);
In the screenshot you can see the extra characters and I attempt to get past them by getting the substring past them. The string then looks good but then throws an exception about a hexadecimal value 0x0B further ahead in the string.
Can anyone give this a look? Thanks.
--Screenshot with as much info as possible
I don't have the reputation to stick the image in I hope the link works.
private static byte[] ObjectToByteArray(Object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
o is already an array of bytes (as seen in the debugger). Deserializing it again makes no sense. Just cast object o to byte[] and then run the Encoding.GetString method on it.

Why do I get an array of zero

myByte - all bytes are zero
a = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
var memoryStream = new MemoryStream();
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, m_workspace.ListPlatforms.ToArray());
myByte = new byte[memoryStream.Length];
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.Write(myByte, 0, myByte.Length);
string a = System.Convert.ToBase64String(myByte);
what could be the reason
You're calling Write when I suspect you meant to call Read. In other words, you're writing from a newly created (and thus full-of-zeroes) array to the MemoryStream which has your serialized data in. Using Read instead of Write will read into the array from the stream.
It would be simpler to call ToArray though:
byte[] myByte = memoryStream.ToArray();
You're writing the byte array into the MemoryStream, not the other way round. Replacing Write with read would fix your immediate problem.
But MemoryStream has a ToArray() method which already does what you want. No need to do it in such a complicated way.
Reasons:
you didn't flush binaryFormatter so the memoryStream didn't even got written
what are you trying to do anyway!?
If (1) is correct, put using around both memoryStream and binaryFormatter.

C# binary to string

I am converting integer number to binary and put it in a header of a data message.
For instance the first meesage that arrived, I would convert the counter to binary that take 4 bytes and had the data message, which is a reguler message containning a, b, c etc'.
Here is how I convert the counter :
//This is preparing the counter as binaryint
nCtrIn = ...;
int nCtrInNetwork = System.Net.IPAddress.HostToNetworkOrder(nCtrIn);
byte[] ArraybyteFormat = BitConverter.GetBytes(nCtrInNetwork);
Now the problem is that now in to take a nother string copy the byteFormat to the beginning of a string and in addition to add the string data.
I do that because I want only in the end to write to the file using binary writer
m_brWriter.Write(ArraybyteFormat);
m_brWriter.Flush();
You can simplify by letting the BinaryWriter directly write the int - no need to conver to byte[] first.
The other problem is writing the message, it can be done like:
m_brWriter.Write(nCounterIn);
string msg = ....; // get it as 1 big string
byte[] textData = Encoding.UTF8.GetBytes(msg);
m_brWriter.Write(textData);
Or, even easier and also easier to read back:
m_brWriter.Write(nCounterIn);
m_brWriter.Write(msg);
But note that the BinaryWriter will now put it's own lentgh-prefix in front of the string.
If it's important to write to the stream in single call you can concatenate the arrays:
var intArray = new byte[4]; // In real code assign
var stringArray = new byte[12]; // actual arrays
var concatenated = new byte[16];
intArray.CopyTo(concatenated, 0);
stringArray.CopyTo(concatenated, 4);
m_brWriter.Write(concatenated);
m_brWriter.Flush();
Did you consider writing the arrays in two calls to Write?

Categories

Resources