I'm trying to serialize/deserialize a string array in c# but getting this error -
System.Runtime.Serialization.SerializationException : End of Stream
encountered before parsing was completed.
Here is my code:
void SerializeFunc(ISession session, string key, object toSerialize)
{
var binaryFormatter = new BinaryFormatter();
var memoryStream = new MemoryStream();
binaryFormatter.Serialize(memoryStream, toSerialize);
session.Set(key, memoryStream.ToArray());
memoryStream.Flush();
memoryStream.Close();
memoryStream.Dispose();
}
object DeSerializeFunc(ISession session, string key)
{
var memoryStream = new MemoryStream();
var binaryFormatter = new BinaryFormatter();
var objectBytes = session.Get(key) as byte[];
memoryStream.Write(objectBytes, 0, objectBytes.Length);
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.Position = 0;
var valueObject = binaryFormatter.Deserialize(memoryStream); //ERROR
memoryStream.Close();
memoryStream.Dispose();
return valueObject;
}
public class CustomSession : Microsoft.AspNetCore.Http.ISession
{
Dictionary<string, object> sessionStorage = new Dictionary<string, object>();
void ISession.Set(string key, byte[] value)
{
sessionStorage[key] = value;
}
bool ISession.TryGetValue(string key, out byte[] value)
{
if (sessionStorage[key] != null)
{
value = Encoding.ASCII.GetBytes(sessionStorage[key].ToString());
return true;
}
else
{
value = null;
return false;
}
}
// remove other Interface members for simplicity..
}
var session = new CustomSession();
SerializeFunc(session, "key1", new string[] { "one", "two", "three" });
var obj = DeSerializeFunc(session, "key1"); //ERROR
What am I doing wrong here?
Related
I'm trying to convert/cast an image source to an object. I tried to convert to a byte prior to object.
ImageSource oImageSelectedByUser = (from ii in mySource where ii.PhotoImgStream != null select ii.PhotoImgStream).FirstOrDefault();
var oImageAsByte = await ConvertStreamtoByteAsync(oImageSelectedByUser);
var oImageAsObject = FromByteArray<object>(oImageAsByte);
private static async Task<byte[]> ConvertStreamtoByteAsync(ImageSource imageSource)
{
byte[] buffer = new byte[16 * 1024];
try
{
if (imageSource is FileImageSource)
{
FileImageSource objFileImageSource = (FileImageSource)imageSource;
string strFileName = objFileImageSource.File;
var webClient = new WebClient();
buffer = await webClient.DownloadDataTaskAsync(new Uri(strFileName));
return buffer;
}
}
catch (Exception ex)
{
buffer = null;
}
return buffer;
}
public T FromByteArray<T>(byte[] data)
{
if (data == null)
return default(T);
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(data))
{
object obj = bf.Deserialize(ms);
return (T)obj;
}
}
When trying to convert to object, the error I get is:
Binary stream '0' does not contain a valid BinaryHeader. Possible
causes are invalid stream or object version change between
serialization and deserialization.
I wanted to ask is there a better way to do this?
Any direction/pointers appreciated.
You could modify the code like following
public T FromByteArray<T>(byte[] data)
{
if (data == null)
return default(T);
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(data))
{
ms.Seek(0, SeekOrigin.Begin); // /rewinded the stream to the begining.
object obj = bf.Deserialize(ms);
return (T)obj;
}
}
I have the following code to serialize decrypted and deserialize encrypted objects from a binary file. Writing decrypted objects works well. However, when attempting to de-serialize decrypted objects from the file, it fails after the first object successfully de-serialized.
I was hoping that someone could point me to the error, as I ran out of ideas.
Writing encrypted objects to a binary file works perfectly well
public List ReadAllObjectsFromFile(string pPath)
{
List objList = null;
T obj = default(T);
using (FileStream stream = new FileStream(pPath, FileMode.Open, FileAccess.Read))
{
while (true)
{
if (stream.Length>m_ReaderPosition)
{
stream.Seek(m_ReaderPosition, SeekOrigin.Begin);
if (IsEncrypted)
{
using (Stream cryptoStream = new CryptoStream(stream, m_Decryptor, CryptoStreamMode.Read))
{
if (objList == null) objList = new List();
obj = (T)m_Formatter.Deserialize(cryptoStream);
}
}
else
{
if (objList == null) objList = new List();
obj = (T)m_Formatter.Deserialize(stream);
}
m_ReaderPosition = stream.Position;
}
if ((IsReadToEnd = object.Equals(obj, default(T)))) break;
else
{
objList.Add(obj);
obj = default(T);
}
}
}
return objList;
}
Trying to read the encrypted objects from the binary file and deserialize them into de-crypted objects throw as exception at the second object it attempts to deserialize
"System.Runtime.Serialization.SerializationException: 'The input
stream is not a valid binary format. The starting contents (in bytes)
are: 83-AD-D4-BB-F9-7A-4E-34-C2-E7-4F-0C-4F-51-F2-1E-EC .."
The method successfully de-serialized the first object though.
This line of code triggers the exception on second object.
obj = (T)m_Formatter.Deserialize(cryptoStream);
public List ReadAllObjectsFromFileEnc(string pPath)
{
List objList = null;
T obj = default(T);
using (FileStream stream = new FileStream(pPath, FileMode.Open, FileAccess.Read))
{
using (Stream cryptoStream = new CryptoStream(stream, m_Decryptor, CryptoStreamMode.Read))
{
while (true)
{
if (stream.Length>m_ReaderPosition)
{
stream.Seek(m_ReaderPosition, SeekOrigin.Begin);
if (objList == null) objList = new List();
obj = (T)m_Formatter.Deserialize(cryptoStream);
m_ReaderPosition = stream.Position;
}
if ((IsReadToEnd = object.ReferenceEquals(obj, default(T)))) break;
else
{
objList.Add(obj);
obj = default(T);
}
}
}
return objList;
}
}
Main
static void Main(string[] args)
{
List objList = new List();
objList.Add(
new Bear()
{
Name = "John",
Age = 35,
Birth = new DateTime(1977, 02, 02),
Females = new KeyValuePair("Dove", "Mumu")
});
objList.Add(
new Bear()
{
Name = "Max",
Age = 40,
Birth = new DateTime(1977, 08, 02),
Females = new KeyValuePair("Gr", "Mumu")
});
objList.Add(
new Bear()
{
Name = "Mika",
Age = 21,
Birth = new DateTime(1990, 02, 02),
Females = new KeyValuePair("Dr", "Mumu")
});
objList.Add(
new Bear()
{
Name = "Miles",
Age = 90,
Birth = new DateTime(1901, 02, 02),
Females = new KeyValuePair("SE", "Mumu")
});
BinarySerializer binser = new BinarySerializer(#"E:\Temp\myFile.bin", 10000, true, "My Encryption is here");
foreach(Bear t in objList)
binser.WriteObjectToFile(binser.FileDetails.FullName, t);
objList = null;
objList = binser.ReadAllObjectsFromFileEnc(binser.FileDetails.FullName);
}
Here's the write to file
public void WriteObjectToFile(string pPath, object pObject)
{
using (FileStream stream = new FileStream(pPath, FileMode.Append, FileAccess.Write))
{
if (IsEncrypted)
{
using (Stream cryptoStream = new CryptoStream(stream, m_Encryptor, CryptoStreamMode.Write))
{
// 3. write to the cryptoStream
m_Formatter.Serialize(cryptoStream, pObject);
}
}
else
m_Formatter.Serialize(stream, pObject);
}
}
I am compressing a json using deflate compression technique and saving to sql server database. The json contains values from any culture ie. th-TH, zh-TW. The compressed string is getting saved successfully in database.
Json includes data like {"#id":"2113","description":"อาหารเช้าคอนติเนนทัล"}
Now when i read the same data from db, i convert it to bytes as
Encoding encoding = Encoding.UTF8;
encoding.GetBytes(data ?? string.Empty)
The compression like this
public static string Compress(this string data, CompressionTypeOptions compressionType)
{
var bytes = Compress(Encoding.UTF-8.GetBytes(data ?? string.Empty), compressionType);
return Encoding.UTF-8.GetString(bytes);
}
}
private static byte[] Compress(byte[] data, CompressionTypeOptions compressionType)
{
using (var memoryStream1 = new MemoryStream(data))
{
using (var memoryStream2 = new MemoryStream())
{
using (var compressionStream = CreateCompressionStream(compressionType, (Stream)memoryStream2,
CompressionMode.Compress))
{
CopyTo((Stream)memoryStream1, compressionStream);
compressionStream.Close();
return memoryStream2.ToArray();
}
}
}
}
Then decompressing like this
using (var memoryStream = new MemoryStream(data))
{
using (var compressionStream = CreateCompressionStream(compressionType, (Stream)memoryStream,
CompressionMode.Decompress))
return ReadAllBytesFromStream(compressionStream);
}
Here is ReadAllBytesFromStream definition
private static byte[] ReadAllBytesFromStream(Stream stream)
{
using (var memoryStream = new MemoryStream())
{
var buffer1 = new byte[1];
while (true)
{
int count = stream.Read(buffer1, 0, 1);
if (count != 0)
memoryStream.Write(buffer1, 0, count);
else
break;
}
var length = memoryStream.Length;
var buffer2 = new byte[length];
memoryStream.Position = 0L;
memoryStream.Read(buffer2, 0, (int)length);
return buffer2;
}
}
Getting error at int count = stream.Read(buffer1, 0, 1); as
'System.IO.InvalidDataException'
'Unknown block type. Stream might be corrupted.'
Any help is appreaciated
I want to convert an objeect of byte[][] type to Dictonary.
It always give an error "End of Stream encountered before parsing was completed."
Please help me .
public static object ByteToObjectArray(byte[][] ms)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream mStream = new MemoryStream();
mStream.Write(ms, 0, (int)ms.Length);
mStream.Position = 0;
return formatter.Deserialize(mStream) as object;
}
The HGETALL should return the data as
key1
data1
key2
data2
...
So interleaved... Now... Supposing the key is in UTF8:
public static Dictionary<string, object> ByteToObjectArray(byte[][] bytes)
{
var dict = new Dictionary<string, object>();
var formatter = new BinaryFormatter();
for (int i = 0; i < bytes.Length; i += 2)
{
string key = Encoding.UTF8.GetString(bytes[i]);
// Alternatively
//string key = Encoding.Unicode.GetString(bytes[i]);
using (var stream = new MemoryStream(bytes[i + 1]))
{
object obj = formatter.Deserialize(stream);
dict.Add(key, obj);
}
}
return dict;
}
I am trying to convert class to byte but not worked.
I receive a byte[] (b) with zero length . why ?
void start()
{
Item item = new Item();
item.files.Add(#"test");
byte[] b = ObjectToByteArray(item); // b will have zero length
}
[Serializable]
public class Item : ISerializable
{
public Item()
{
files = new List<string>();
Exclude = false;
CleanEmptyFolder = false;
}
public List<string> files;
public string MusicProfileName;
public bool Exclude;
#region ISerializable Members
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("files", files);
info.AddValue("MusicProfileName", MusicProfileName);
info.AddValue("Exclude", Exclude);
}
#endregion
}
public byte[] ObjectToByteArray(object _Object)
{
using (var stream = new MemoryStream())
{
// serialize object
var formatter = new BinaryFormatter();
formatter.Serialize(stream, _Object);
// get a byte array
var bytes = new byte[stream.Length];
using (BinaryReader br = new BinaryReader(stream))
{
bytes = br.ReadBytes(Convert.ToInt32(stream.Length));
}
return bytes;
}
}
You didn't reset the MemoryStream before you started to read from it. The position is at the end of the stream, so you get an empty array.
Use the ToArray method instead, it gets the entire content regardless of the current position:
public byte[] ObjectToByteArray(object _Object) {
using (var stream = new MemoryStream()) {
// serialize object
var formatter = new BinaryFormatter();
formatter.Serialize(stream, _Object);
// get a byte array
return stream.ToArray();
}
}
Try using MemoryStream.ToArray instead of trying to read from the MemoryStream with a BinaryReader:
return stream.ToArray();
The problem is that you aren't resetting the stream, so it's trying to read from the end instead of the beginning. You could also seek back to the beginning of the stream:
stream.Seek(0, SeekOrigin.Begin);