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.
I want to iterate through the values of a specific path and read them.
I tried this
Code updated
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Internet Explorer\IntelliForms\Storage2", true);
var names = key.GetValueNames();
for (int i = 0; i < names.Length; i++)
{
Console.WriteLine(names[i]);
byte[] test = ObjectToByteArray(key.GetValue(names[i]));
var value = Convert.ToBase64String(test);
Console.WriteLine(value);
};
Normally the string value should be an encrypted binary.
Update: So as #Peter Lillevold suggested I had to convert the array of bytes into a string.
To do so, I created this small function to convert the object key.GetValue into an array of bytes
public static byte[] ObjectToByteArray(Object obj)
{
if (obj == null)
return null;
BinaryFormatter Binaryform = new BinaryFormatter();
MemoryStream MemStream = new MemoryStream();
Binaryform.Serialize(MemStream, obj);
return MemStream.ToArray();
}
and then converted to a string as #Peter suggested.
So after the convertion of the array of bytes it is supposed to return me a string of binary.
What I get is some weird combination of letters and digits but it is not binary.
Any help on this?
You get "System.Byte[]" because you take an instance of byte[] and calls ToString() on it. This will not convert the content of the byte array into text, for that you would use something like Convert.ToBase64String or Encoding.UTF8.GetString. More discussion on the topic in this SO question.
I'm trying to convert an object which I have in a byte[] to an object.
I've tried using this code I found online:
object byteArrayToObject(byte[] bytes)
{
try
{
MemoryStream ms = new MemoryStream(bytes);
BinaryFormatter bf = new BinaryFormatter();
//ms.Position = 0;
return bf.Deserialize(ms,null);
}
catch
{
return null;
}
}
SerializationException: "End of Stream encountered before parsing was
completed.".
I've tried it with the ms.Position = 0 line uncommented of course too...
bytes[] is only 8 bytes long, each byte isn't null.
Suggestions?
[edit]
The byte[] was written to a binary file from a c++ program using something along the lines of
void WriteToFile (std::ostream& file,T* value)
{
file.write(reinterpret_cast<char*>(value), sizeof(*T))
}
Where value may be a number of different types.
I can cast to some objects okay from the file using BitConverter, but anything BitConverter doesn't cover I can't do..
As was stated by cdhowie, you will need to manually deserialize the encoded data. Based on the limited information available, you may either want an array of objects or an object containing an array. It looks like you have a single long but there is no way to know from your code. You will need to recreate your object in its true form so take the below myLong as a simple example for a single long array. Since it was unspecified I'll assume you want a struct containing an array like:
public struct myLong {
public long[] value;
}
You could do the same thing with an array of structs, or classes with minor changes to the code posted below.
Your method will be something like this: (written in the editor)
private myLong byteArrayToObject(byte[] bytes) {
try
{
int len = sizeof(long);
myLong data = new myLong();
data.value = new long[bytes.Length / len];
int byteindex = 0;
for (int i = 0; i < data.value.Length; i++) {
data.value[i] = BitConverter.ToInt64(bytes,byteindex);
byteindex += len;
}
return data;
}
catch
{
return null;
}
}
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.
I am writing a prototype TCP connection and I am having some trouble homogenizing the data to be sent.
At the moment, I am sending nothing but strings, but in the future we want to be able to send any object.
The code is quite simple at the moment, because I thought everything could be cast into a byte array:
void SendData(object headerObject, object bodyObject)
{
byte[] header = (byte[])headerObject; //strings at runtime,
byte[] body = (byte[])bodyObject; //invalid cast exception
// Unable to cast object of type 'System.String' to type 'System.Byte[]'.
...
}
This of course is easily enough solved with a
if( state.headerObject is System.String ){...}
The problem is, if I do it that way, I need to check for EVERY type of object that can't be cast to a byte[] at runtime.
Since I do not know every object that can't be cast into a byte[] at runtime, this really isn't an option.
How does one convert any object at all into a byte array in C# .NET 4.0?
Use the BinaryFormatter:
byte[] ObjectToByteArray(object obj)
{
if(obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
Note that obj and any properties/fields within obj (and so-on for all of their properties/fields) will all need to be tagged with the Serializable attribute to successfully be serialized with this.
checkout this article :http://www.morgantechspace.com/2013/08/convert-object-to-byte-array-and-vice.html
Use the below code
// Convert an object to a byte array
private byte[] ObjectToByteArray(Object obj)
{
if(obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
// Convert a byte array to an Object
private Object ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object) binForm.Deserialize(memStream);
return obj;
}
Like others have said before, you could use binary serialization, but it may produce an extra bytes or be deserialized into an objects with not exactly same data. Using reflection on the other hand is quite complicated and very slow.
There is an another solution that can strictly convert your objects to bytes and vise-versa - marshalling:
var size = Marshal.SizeOf(your_object);
// Both managed and unmanaged buffers required.
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
// Copy object byte-to-byte to unmanaged memory.
Marshal.StructureToPtr(your_object, ptr, false);
// Copy data from unmanaged memory to managed buffer.
Marshal.Copy(ptr, bytes, 0, size);
// Release unmanaged memory.
Marshal.FreeHGlobal(ptr);
And to convert bytes to object:
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(bytes, 0, ptr, size);
var your_object = (YourType)Marshal.PtrToStructure(ptr, typeof(YourType));
Marshal.FreeHGlobal(ptr);
It's noticeably slower and partly unsafe to use this approach for small objects and structs comparing to your own serialization field by field (because of double copying from/to unmanaged memory), but it's easiest way to strictly convert object to byte[] without implementing serialization and without [Serializable] attribute.
Using Encoding.UTF8.GetBytes is faster than using MemoryStream.
Here, I am using NewtonsoftJson to convert input object to JSON string and then getting bytes from JSON string.
byte[] SerializeObject(object value) =>Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value));
Benchmark for #Daniel DiPaolo's version with this version
Method | Mean | Error | StdDev | Median | Gen 0 | Allocated |
--------------------------|----------|-----------|-----------|----------|--------|-----------|
ObjectToByteArray | 4.983 us | 0.1183 us | 0.2622 us | 4.887 us | 0.9460 | 3.9 KB |
ObjectToByteArrayWithJson | 1.548 us | 0.0309 us | 0.0690 us | 1.528 us | 0.3090 | 1.27 KB |
What you're looking for is serialization. There are several forms of serialization available for the .Net platform
Binary Serialization
XML Serialization: Produces a string which is easily convertible to a byte[]
ProtoBuffers
public static class SerializerDeserializerExtensions
{
public static byte[] Serializer(this object _object)
{
byte[] bytes;
using (var _MemoryStream = new MemoryStream())
{
IFormatter _BinaryFormatter = new BinaryFormatter();
_BinaryFormatter.Serialize(_MemoryStream, _object);
bytes = _MemoryStream.ToArray();
}
return bytes;
}
public static T Deserializer<T>(this byte[] _byteArray)
{
T ReturnValue;
using (var _MemoryStream = new MemoryStream(_byteArray))
{
IFormatter _BinaryFormatter = new BinaryFormatter();
ReturnValue = (T)_BinaryFormatter.Deserialize(_MemoryStream);
}
return ReturnValue;
}
}
You can use it like below code.
DataTable _DataTable = new DataTable();
_DataTable.Columns.Add(new DataColumn("Col1"));
_DataTable.Columns.Add(new DataColumn("Col2"));
_DataTable.Columns.Add(new DataColumn("Col3"));
for (int i = 0; i < 10; i++) {
DataRow _DataRow = _DataTable.NewRow();
_DataRow["Col1"] = (i + 1) + "Column 1";
_DataRow["Col2"] = (i + 1) + "Column 2";
_DataRow["Col3"] = (i + 1) + "Column 3";
_DataTable.Rows.Add(_DataRow);
}
byte[] ByteArrayTest = _DataTable.Serializer();
DataTable dt = ByteArrayTest.Deserializer<DataTable>();
Combined Solutions in Extensions class:
public static class Extensions {
public static byte[] ToByteArray(this object obj) {
var size = Marshal.SizeOf(data);
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(data, ptr, false);
Marshal.Copy(ptr, bytes, 0, size);
Marshal.FreeHGlobal(ptr);
return bytes;
}
public static string Serialize(this object obj) {
return JsonConvert.SerializeObject(obj);
}
}
How about something simple like this?
return ((object[])value).Cast<byte>().ToArray();
You could use the built-in serialization tools in the framework and serialize to a MemoryStream. This may be the most straightforward option, but might produce a larger byte[] than may be strictly necessary for your scenario.
If that is the case, you could utilize reflection to iterate over the fields and/or properties in the object to be serialized and manually write them to the MemoryStream, calling the serialization recursively if needed to serialize non-trivial types. This method is more complex and will take more time to implement, but allows you much more control over the serialized stream.
I'd rather use the expression "serialization" than "casting into bytes". Serializing an object means converting it into a byte array (or XML, or something else) that can be used on the remote box to re-construct the object. In .NET, the Serializable attribute marks types whose objects can be serialized.
One additional implementation, which uses Newtonsoft.Json binary JSON and does not require marking everything with the [Serializable] attribute. Only one drawback is that an object has to be wrapped in anonymous class, so byte array obtained with binary serialization can be different from this one.
public static byte[] ConvertToBytes(object obj)
{
using (var ms = new MemoryStream())
{
using (var writer = new BsonWriter(ms))
{
var serializer = new JsonSerializer();
serializer.Serialize(writer, new { Value = obj });
return ms.ToArray();
}
}
}
Anonymous class is used because BSON should start with a class or array.
I have not tried to deserialize byte[] back to object and not sure if it works, but have tested the speed of conversion to byte[] and it completely satisfies my needs.
Alternative way to convert object to byte array:
TypeConverter objConverter = TypeDescriptor.GetConverter(objMsg.GetType());
byte[] data = (byte[])objConverter.ConvertTo(objMsg, typeof(byte[]));