By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,701 Members | 1,955 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,701 IT Pros & Developers. It's quick & easy.

Serializing a Hashtable

P: n/a
I know how to take a single hashtable, and then use a binaryformatter
and a filestream to dump it to a file, but I need to serialize and
deserialize a hashtable inside a class. I've been trying this:

[XmlIgnore]
public Hashtable Directions;

public byte[] DirectionsSerialized
{
get
{
byte[] bData = new byte[1024];
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream(bData);
memoryStream.Position = 0;
formatter.Serialize(memoryStream, Directions);

return bData;
}
set
{
MemoryStream memoryStream = new MemoryStream();
memoryStream.Write(value, 0, value.Length);
BinaryFormatter bf = new BinaryFormatter();
memoryStream.Position = 0;
Directions = (Hashtable)bf.Deserialize(memoryStream);
}
}

Which appears to serialize fine, but upon deserialization, it throws an
error:

"'', hexadecimal value 0x1B, is an invalid character. Line 299,
position 18."

Thanks guys.

Nov 17 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Mio,

A few things.

The first is that you don't really have to initialize the memory stream
with your array when serializing the instance, since it will allocate space
as needed when the serializer writes to it.

The other thing about this is that when you pass the byte array to the
constructor, it makes the memory stream fixed-size. So if you need more
than one kilobyte for the serialized instance, it will throw an exception.

Additionally, when you are returning the byte array, it contains extra
bytes that are not part of the serialized instance (in the case where you
need less than 1K).

Your get code should look like this:

// Create the formatter.
BinaryFormatter formatter = new BinaryFormatter();

// Create the stream.
using (MemoryStream memoryStream = new MemoryStream())
{
// No need to set the position, since it is already at 0.
// Serialize the instance.
formatter.Serialize(memoryStream, Directions);

// Return the array. This will be properly sized.
return memoryStream.ToArray();
}

Now, when dealing with deserializing the instance, your code should work
just fine. However, it could stand to be cleaned up, like so:

// Pass the value into the memory stream, since we are just reading.
using (MemoryStream memoryStream = new MemoryStream(value))
{
// Create the formatter.
BinaryFormatter bf = new BinaryFormatter();

// Set the hashtable.
Directions = (Hashtable) bf.Deserialize(memoryStream);
}

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
<Mi*********@gmail.com> wrote in message
news:11*********************@g14g2000cwa.googlegro ups.com...
I know how to take a single hashtable, and then use a binaryformatter
and a filestream to dump it to a file, but I need to serialize and
deserialize a hashtable inside a class. I've been trying this:

[XmlIgnore]
public Hashtable Directions;

public byte[] DirectionsSerialized
{
get
{
byte[] bData = new byte[1024];
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream(bData);
memoryStream.Position = 0;
formatter.Serialize(memoryStream, Directions);

return bData;
}
set
{
MemoryStream memoryStream = new MemoryStream();
memoryStream.Write(value, 0, value.Length);
BinaryFormatter bf = new BinaryFormatter();
memoryStream.Position = 0;
Directions = (Hashtable)bf.Deserialize(memoryStream);
}
}

Which appears to serialize fine, but upon deserialization, it throws an
error:

"'', hexadecimal value 0x1B, is an invalid character. Line 299,
position 18."

Thanks guys.
Nov 17 '05 #2

P: n/a
Thanks Nicholas.

That works perfectly.

Nicholas Paldino [.NET/C# MVP] wrote:
Mio,

A few things.

The first is that you don't really have to initialize the memory stream
with your array when serializing the instance, since it will allocate space
as needed when the serializer writes to it.

The other thing about this is that when you pass the byte array to the
constructor, it makes the memory stream fixed-size. So if you need more
than one kilobyte for the serialized instance, it will throw an exception.

Additionally, when you are returning the byte array, it contains extra
bytes that are not part of the serialized instance (in the case where you
need less than 1K).

Your get code should look like this:

// Create the formatter.
BinaryFormatter formatter = new BinaryFormatter();

// Create the stream.
using (MemoryStream memoryStream = new MemoryStream())
{
// No need to set the position, since it is already at 0.
// Serialize the instance.
formatter.Serialize(memoryStream, Directions);

// Return the array. This will be properly sized.
return memoryStream.ToArray();
}

Now, when dealing with deserializing the instance, your code should work
just fine. However, it could stand to be cleaned up, like so:

// Pass the value into the memory stream, since we are just reading.
using (MemoryStream memoryStream = new MemoryStream(value))
{
// Create the formatter.
BinaryFormatter bf = new BinaryFormatter();

// Set the hashtable.
Directions = (Hashtable) bf.Deserialize(memoryStream);
}

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
<Mi*********@gmail.com> wrote in message
news:11*********************@g14g2000cwa.googlegro ups.com...
I know how to take a single hashtable, and then use a binaryformatter
and a filestream to dump it to a file, but I need to serialize and
deserialize a hashtable inside a class. I've been trying this:

[XmlIgnore]
public Hashtable Directions;

public byte[] DirectionsSerialized
{
get
{
byte[] bData = new byte[1024];
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream(bData);
memoryStream.Position = 0;
formatter.Serialize(memoryStream, Directions);

return bData;
}
set
{
MemoryStream memoryStream = new MemoryStream();
memoryStream.Write(value, 0, value.Length);
BinaryFormatter bf = new BinaryFormatter();
memoryStream.Position = 0;
Directions = (Hashtable)bf.Deserialize(memoryStream);
}
}

Which appears to serialize fine, but upon deserialization, it throws an
error:

"'', hexadecimal value 0x1B, is an invalid character. Line 299,
position 18."

Thanks guys.


Nov 17 '05 #3

P: n/a


Mi*********@gmail.com wrote:
I know how to take a single hashtable, and then use a binaryformatter
and a filestream to dump it to a file, but I need to serialize and
deserialize a hashtable inside a class.


You could simply mark the containing class serializable, and let the
caller store that, but lookin at you example code I suspect you wish to
run some transformation when serializing/deserializing.

If that is the case, you can use a variant of the Memento pattern, where
you generate an opaque "memento" object that can be used to restore the
state. This object can be serialized by the caller if need be.

// not serializable
public class Foo {
// loads of state in here, perhaps duplicated
// references for efficiency and whatnot

[Serializable]
protected class Memento {
public Hashtable Directions;
public Memento(Foo foo) {
this.Directions = extract_direction_state(foo);
}
}
public object DirectionMemento {
get {
return new Memento(()); }
set {
reestablish_direction_state((Memento)value); }
}
}
}

The user will then do:

Foo foo = new Foo();
// lots of stuff, then need to save foo state:
someFormatter.Serialize(someStream, foo.DirectionMemento);
// do stuff, later restore foo state:
foo.DirectionMemento = someFormatter.Deserialize(someStream);

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.