Index: src/graph/graph.hh
===================================================================
--- src/graph/graph.hh	(revision 46)
+++ src/graph/graph.hh	(working copy)
@@ -131,8 +131,8 @@
     void ComputeGraphLayoutSpringBlock(size_t iter = 0, size_t seed = 4357);
 
     // i/o
-    void WriteToFile(std::string s); 
-    void ReadFromFile(std::string s); 
+    void WriteToFile(std::string s, std::string t);
+    void ReadFromFile(std::string s, std::string t);
 
     // signal handling
     void InitSignalHandling();
Index: src/graph/graph_io.cc
===================================================================
--- src/graph/graph_io.cc	(revision 46)
+++ src/graph/graph_io.cc	(working copy)
@@ -178,24 +178,37 @@
 
 
 //==============================================================================
-// ReadFromFile(file)
+// ReadFromFile(file, format)
 //==============================================================================
 
-void GraphInterface::ReadFromFile(string file)
+void GraphInterface::ReadFromFile(string file, string format)
 {
     try
     {
-	std::ifstream file_stream(file.c_str(), std::ios_base::in | std::ios_base::binary);
+	bool graphviz = false;
+	if(format == "from_file_extension")
+	    graphviz = boost::ends_with(file,".dot") || boost::ends_with(file,".dot.gz") || boost::ends_with(file,".dot.bz2");
+	else if(format == "dot")
+	    graphviz = true;
+	else if(format != "xml")
+	    throw GraphException("error reading from file '" + file + "': requested invalid format '" + format + "'");
+
 	boost::iostreams::filtering_stream<boost::iostreams::input>  stream;
-	file_stream.exceptions(ios_base::badbit | ios_base::failbit);
-	if (boost::ends_with(file,".gz"))
-	    stream.push(boost::iostreams::gzip_decompressor());
-	if (boost::ends_with(file,".bz2"))
-	    stream.push(boost::iostreams::bzip2_decompressor());
-	stream.push(file_stream);
+	std::ifstream file_stream;
+	if (file == "-")
+	    stream.push(std::cin);
+	else
+	{
+	    file_stream.open(file.c_str(), std::ios_base::in | std::ios_base::binary);
+	    file_stream.exceptions(ios_base::badbit | ios_base::failbit);
+	    if (boost::ends_with(file,".gz"))
+		stream.push(boost::iostreams::gzip_decompressor());
+	    if (boost::ends_with(file,".bz2"))
+		stream.push(boost::iostreams::bzip2_decompressor());
+	    stream.push(file_stream);
+	}
 	stream.exceptions(ios_base::badbit);
 
-	bool graphviz = boost::ends_with(file,"dot") || boost::ends_with(file,"dot.gz") || boost::ends_with(file,"dot.bz2");
 	_properties = dynamic_properties();
 	_mg.clear();
 
@@ -226,7 +239,7 @@
 };
 
 //==============================================================================
-// WriteToFile(file)
+// WriteToFile(file, format)
 //==============================================================================
 struct write_to_file
 {
@@ -279,21 +292,34 @@
 };
 
 
-void GraphInterface::WriteToFile(string file)
+void GraphInterface::WriteToFile(string file, string format)
 {
     try
     {
-	std::ofstream file_stream(file.c_str(), std::ios_base::out | std::ios_base::binary);
+	bool graphviz = false;
+	if(format == "from_file_extension")
+	    graphviz = boost::ends_with(file,".dot") || boost::ends_with(file,".dot.gz") || boost::ends_with(file,".dot.bz2");
+	else if(format == "dot")
+	    graphviz = true;
+	else if(format != "xml")
+	    throw GraphException("error writing to file '" + file + "': requested invalid format '" + format + "'");
+
 	boost::iostreams::filtering_stream<boost::iostreams::output> stream;
-	file_stream.exceptions(ios_base::badbit | ios_base::failbit);
-	if (boost::ends_with(file,".gz"))
-	    stream.push(boost::iostreams::gzip_compressor());
-	if (boost::ends_with(file,".bz2"))
-	    stream.push(boost::iostreams::bzip2_compressor());
-	stream.push(file_stream);
+	std::ofstream file_stream;
+	if (file == "-")
+	    stream.push(std::cout);
+	else
+	{
+	    file_stream.open(file.c_str(), std::ios_base::out | std::ios_base::binary);
+	    file_stream.exceptions(ios_base::badbit | ios_base::failbit);
+	    if (boost::ends_with(file,".gz"))
+		stream.push(boost::iostreams::gzip_compressor());
+	    if (boost::ends_with(file,".bz2"))
+		stream.push(boost::iostreams::bzip2_compressor());
+	    stream.push(file_stream);
+	}
 	stream.exceptions(ios_base::badbit | ios_base::failbit);
-	
-	bool graphviz =  boost::ends_with(file,"dot") || boost::ends_with(file,"dot.gz") || boost::ends_with(file,"dot.bz2");
+
 	dynamic_properties_copy dp = _properties;
 
 	if (IsVertexFilterActive())
Index: src/graph-tool
===================================================================
--- src/graph-tool	(revision 46)
+++ src/graph-tool	(working copy)
@@ -285,15 +285,25 @@
 
 
 def parse_option(opt, just_file=False):
-    "this will execute an aption, and return either None, or a tuple with the result and the respective file name, if it exists"
+    "this will execute an option, and return either None, or a tuple with the result and the respective file name, if it exists"
     if opt.name == "load":
+	values = parse_values(opt.value)
+	if len(values) > 2:
+	    raise OptionError(opt.name, "invalid value '$s'" % opt.value)
+	if len(values) == 1:
+	    values.append("from_file_extension")
         if just_file:
             return None
-        graph.ReadFromFile(opt.value)
+        graph.ReadFromFile(values[0], values[1])
     elif opt.name == "save":
+	values = parse_values(opt.value)
+	if len(values) > 2:
+	    raise OptionError(opt.name, "invalid value '$s'" % opt.value)
+	if len(values) == 1:
+	    values.append("from_file_extension")
         if just_file:
             return None
-        graph.WriteToFile(opt.value)
+	graph.WriteToFile(values[0], values[1])
     elif opt.name == "correlated-configurational-model":
         if just_file:
             return None
