diff --git a/SweetLib.IO/Classes/Streaming/StreamExceptions.cs b/SweetLib.IO/Classes/Streaming/StreamExceptions.cs
new file mode 100644
index 0000000..fd418fa
--- /dev/null
+++ b/SweetLib.IO/Classes/Streaming/StreamExceptions.cs
@@ -0,0 +1,38 @@
+using System.IO;
+
+namespace SweetLib.IO.Classes.Streaming
+{
+ ///
+ /// Exception thrown by streaming related operations.
+ ///
+ public class StreamException : IOException
+ {
+ ///
+ /// Creates a new .
+ ///
+ public StreamException() { }
+
+ ///
+ /// Creates a new .
+ ///
+ /// Exception message.
+ public StreamException(string message) : base(message) { }
+ }
+
+ ///
+ /// Exception thrown by streaming related operations. May be thrown if the stream types do not match.
+ ///
+ public class StreamTypeException : StreamException
+ {
+ ///
+ /// Creates a new .
+ ///
+ public StreamTypeException() { }
+
+ ///
+ /// Creates a new .
+ ///
+ /// Exception message.
+ public StreamTypeException(string message) : base(message) { }
+ }
+}
diff --git a/SweetLib.IO/Classes/Streaming/StreamManager.cs b/SweetLib.IO/Classes/Streaming/StreamManager.cs
new file mode 100644
index 0000000..4ac9182
--- /dev/null
+++ b/SweetLib.IO/Classes/Streaming/StreamManager.cs
@@ -0,0 +1,71 @@
+using System.IO;
+using SweetLib.Utils.Extensions;
+
+namespace SweetLib.IO.Classes.Streaming
+{
+ public static class StreamManager
+ {
+ enum StreamedObjectType : ushort // 2 bytes
+ {
+ Unknown = 0x0000,
+ StringValue = 0x1100,
+ BoolValue = 0x1200,
+ CharValue = 0x1300,
+ IntValue = 0x1400,
+ LongValue = 0x1410,
+ FloatValue = 0x1500,
+ DoubleValue = 0x1600,
+ DateTimeValue = 0x1700,
+ StreamValue = 0x1800,
+ ObjectValue = 0x1900,
+ }
+
+ private static bool SaveMetaToStream(Stream stream, StreamedObjectType type, long length)
+ {
+ stream.Write(((ushort)type).ToBytes(), 0, sizeof(ushort));
+ stream.Write(length.ToBytes(), 0, sizeof(long));
+
+ return true;
+ }
+
+ private static bool LoadMetaDataFromStream(Stream stream, out StreamedObjectType type, out long length)
+ {
+ type = StreamedObjectType.Unknown;
+ length = -1;
+
+ // read object type
+ var buffer = new byte[sizeof(ushort)];
+ stream.Read(buffer, 0, buffer.Length);
+ type = (StreamedObjectType) buffer.ToUInt16();
+
+ // read data length
+ buffer = new byte[sizeof(long)];
+ stream.Read(buffer, 0, buffer.Length);
+ length = buffer.ToInt64();
+
+ return true;
+ }
+
+ public static void SaveToStream(Stream stream, int value)
+ {
+ SaveMetaToStream(stream, StreamedObjectType.IntValue, sizeof(int));
+
+ stream.Write(value.ToBytes(), 0, sizeof(int));
+ }
+
+ public static void LoadFromStream(Stream stream, out int value)
+ {
+ StreamedObjectType type;
+ long length;
+
+ LoadMetaDataFromStream(stream, out type, out length);
+
+ if(type!=StreamedObjectType.IntValue)
+ throw new StreamTypeException($"Expected {StreamedObjectType.IntValue} but found {type} instead.");
+
+ var buffer = new byte[length];
+ stream.Read(buffer, 0, buffer.Length);
+ value = buffer.ToInt32();
+ }
+ }
+}