diff --git a/configure.in b/configure.in
index 88baa03..92b89a2 100644
--- a/configure.in
+++ b/configure.in
@@ -27,6 +27,7 @@ AC_DEFINE_UNQUOTED(LIBGTKHEX_RELEASE_STRING, "$LIBGTKHEX_RELEASE_STRING",
                    [GtkHex library release string.])
 
 PKG_CHECK_MODULES(LIBGTKHEX,
+		  gio-2.0 \
 		  gtk+-2.0 >= 2.4.0	\
 		  atk >= 1.0.0)
 
@@ -97,3 +98,7 @@ icons/32x32/Makefile
 icons/48x48/Makefile
 ghex.spec
 gtkhex.pc])
+
+cat <<EOT
+${CFLAGS}
+EOT
diff --git a/src/ghex-window.c b/src/ghex-window.c
index cdf19ea..44e20ab 100644
--- a/src/ghex-window.c
+++ b/src/ghex-window.c
@@ -1063,6 +1063,8 @@ ghex_window_save_as(GHexWindow *win)
 	const gchar *filename;
 	gboolean dir_flag = FALSE;
     GtkResponseType resp;
+    GFile *gfile = NULL;
+    GFileOutputStream *ostream = NULL;
 
 	if(win->gh == NULL)
 		return ret_val;
@@ -1110,7 +1112,6 @@ ghex_window_save_as(GHexWindow *win)
 	} while (resp == GTK_RESPONSE_OK && dir_flag);	   
 
 	if(resp == GTK_RESPONSE_OK) {
-		FILE *file;
 		gchar *flash;
 		int i;
         gchar *gtk_file_name, *path_end;
@@ -1137,25 +1138,20 @@ ghex_window_save_as(GHexWindow *win)
         }
 
         if(ret_val) {
-            if((file = fopen(filename, "w")) != NULL) {
-                if(hex_document_write_to_file(doc, file)) {
-                    if(doc->file_name)
-                        g_free(doc->file_name);
-                    if(doc->path_end)
-                        g_free(doc->path_end);
-                    doc->file_name = g_strdup(filename);
+            gfile = g_file_new_for_path (filename);
+            ostream = g_file_replace (gfile,
+                    NULL /*etag*/,
+                    TRUE /*make backup*/,
+                    G_FILE_CREATE_NONE,
+                    NULL,
+                    NULL);
+            g_object_unref (gfile);
+            if(ostream) {
+                if(hex_document_write_to_file(doc, ostream)) {
+                    hex_document_set_filename (doc, filename);
                     doc->changed = FALSE;
                     win->changed = FALSE;
 
-                    for(i = strlen(doc->file_name);
-                        (i >= 0) && (doc->file_name[i] != '/');
-                        i--)
-                        ;
-                    if(doc->file_name[i] == '/')
-                        path_end = &doc->file_name[i+1];
-                    else
-                        path_end = doc->file_name;
-                    doc->path_end = g_filename_to_utf8(path_end, -1, NULL, NULL, NULL);
                     ghex_window_set_doc_name(win, doc->path_end);
                     gtk_file_name = g_filename_to_utf8(doc->file_name, -1, NULL, NULL, NULL);
                     flash = g_strdup_printf(_("Saved buffer to file %s"), gtk_file_name);
@@ -1167,7 +1163,8 @@ ghex_window_save_as(GHexWindow *win)
                     display_error_dialog (win, _("Error saving file!"));
                     ret_val = FALSE;
                 }
-                fclose(file);
+                g_output_stream_close (ostream, NULL, NULL);
+                g_object_unref (ostream);
             }
             else {
                 display_error_dialog (win, _("Can't open file for writing!"));
diff --git a/src/hex-document.c b/src/hex-document.c
index 5b5a554..4de5c5e 100644
--- a/src/hex-document.c
+++ b/src/hex-document.c
@@ -23,6 +23,7 @@
 
 #include <config.h>
 #include <glib-object.h>
+#include <gio/gio.h>
 
 #include <gtkhex.h>
 #include <ghex-marshal.h>
@@ -193,15 +194,21 @@ undo_stack_free(HexDocument *doc)
 static gboolean
 get_document_attributes(HexDocument *doc)
 {
-	static struct stat stats;
+	GFileInfo* file_info = NULL;
 
-	if(doc->file_name == NULL)
+	if(!doc->gfile)
 		return FALSE;
 
-	if(!stat(doc->file_name, &stats) &&
-	   S_ISREG(stats.st_mode)) {
-		doc->file_size = stats.st_size;
+	file_info = g_file_query_info (doc->gfile,
+								   "standard::*",
+								   G_FILE_QUERY_INFO_NONE,
+								   NULL,
+								   NULL);
 
+	if(file_info &&
+			g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) {
+		doc->file_size = g_file_info_get_size (file_info);
+		g_object_unref (file_info);
 		return TRUE;
 	}
 
@@ -291,6 +298,9 @@ hex_document_finalize(GObject *obj)
 	if(hex->buffer)
 		g_free(hex->buffer);
 	
+	if(hex->gfile)
+		g_object_unref(hex->gfile);
+
 	if(hex->file_name)
 		g_free(hex->file_name);
 
@@ -439,31 +449,48 @@ hex_document_new()
 	return doc;
 }
 
+void hex_document_set_filename (HexDocument* doc, const gchar *name)
+{
+	GFileInfo* file_info = NULL;
+
+	if(doc->file_name)
+		g_free(doc->file_name);
+	if(doc->path_end)
+		g_free(doc->path_end);
+	if (doc->gfile) {
+		g_object_unref (doc->gfile);
+	}
+
+	doc->file_name = (gchar *)g_strdup(name);
+	doc->gfile = g_file_new_for_path (name);
+
+	/* get the display name of the file */
+	file_info = g_file_query_info (doc->gfile,
+			G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+			G_FILE_QUERY_INFO_NONE,
+			NULL,
+			NULL);
+	if (file_info) {
+		doc->path_end = g_strdup (g_file_info_get_display_name (file_info));
+		g_object_unref (file_info);
+	}
+}
+
 HexDocument *
 hex_document_new_from_file(const gchar *name)
 {
 	HexDocument *doc;
-	gchar *path_end;
 	int i;
 
 	doc = HEX_DOCUMENT (g_object_new (hex_document_get_type(), NULL));
 	g_return_val_if_fail (doc != NULL, NULL);
 
-	doc->file_name = (gchar *)g_strdup(name);
+	hex_document_set_filename (doc, name);
 	if(get_document_attributes(doc)) {
 		doc->gap_size = 100;
 		doc->buffer_size = doc->file_size + doc->gap_size;
 		doc->buffer = (guchar *)g_malloc(doc->buffer_size);
 
-		/* find the start of the filename without path */
-		for(i = strlen(doc->file_name); (i >= 0) && (doc->file_name[i] != '/'); i--)
-			;
-		if(doc->file_name[i] == '/')
-			path_end = &doc->file_name[i+1];
-		else
-			path_end = doc->file_name;
-
-		doc->path_end = g_filename_to_utf8 (path_end, -1, NULL, NULL, NULL);
 		if(hex_document_read(doc)) {
 			doc_list = g_list_append(doc_list, doc);
 			return doc;
@@ -649,22 +676,24 @@ hex_document_delete_data(HexDocument *doc, guint offset, guint len, gboolean und
 gint
 hex_document_read(HexDocument *doc)
 {
-	FILE *file;
+	GFileInputStream* istream = NULL;
 	static HexChangeData change_data;
 
-	if(doc->file_name == NULL)
+	if(doc->gfile == NULL)
 		return FALSE;
 
 	if(!get_document_attributes(doc))
 		return FALSE;
 
-	if((file = fopen(doc->file_name, "r")) == NULL)
+	istream = g_file_read (doc->gfile, NULL, NULL);
+	if (!istream)
 		return FALSE;
 
 	doc->gap_size = doc->buffer_size - doc->file_size;
-	fread(doc->buffer + doc->gap_size, 1, doc->file_size, file);
+	g_input_stream_read (G_INPUT_STREAM (istream), doc->buffer + doc->gap_size, doc->file_size, NULL, NULL);
 	doc->gap_pos = doc->buffer;
-	fclose(file);
+	g_input_stream_close (G_INPUT_STREAM (istream), NULL, NULL);
+	g_object_unref (istream);
 	undo_stack_free(doc);
 
 	change_data.start = 0;
@@ -676,20 +705,20 @@ hex_document_read(HexDocument *doc)
 }
 
 gint
-hex_document_write_to_file(HexDocument *doc, FILE *file)
+hex_document_write_to_file(HexDocument *doc, GOutputStream *ostream)
 {
 	gint ret = TRUE;
 	size_t exp_len;
 
 	if(doc->gap_pos > doc->buffer) {
 		exp_len = MIN(doc->file_size, doc->gap_pos - doc->buffer);
-		ret = fwrite(doc->buffer, 1, exp_len, file);
-		ret = (ret == exp_len)?TRUE:FALSE;
+		ret = g_output_stream_write (ostream, doc->buffer, exp_len, NULL, NULL);
+		ret = (ret == exp_len);
 	}
 	if(doc->gap_pos < doc->buffer + doc->file_size) {
 		exp_len = doc->file_size - (size_t)(doc->gap_pos - doc->buffer);
-		ret = fwrite(doc->gap_pos + doc->gap_size, 1, exp_len, file);
-		ret = (ret == exp_len)?TRUE:FALSE;
+		ret = g_output_stream_write (ostream, doc->gap_pos + doc->gap_size, exp_len, NULL, NULL);
+		ret = (ret == exp_len);
 	}
 
 	return ret;
@@ -698,15 +727,22 @@ hex_document_write_to_file(HexDocument *doc, FILE *file)
 gint
 hex_document_write(HexDocument *doc)
 {
-	FILE *file;
+	GFileOutputStream *ostream;
 	gint ret = FALSE;
 
-	if(doc->file_name == NULL)
+	if(doc->gfile == NULL)
 		return FALSE;
 
-	if((file = fopen(doc->file_name, "w")) != NULL) {
-		ret = hex_document_write_to_file(doc, file);
-		fclose(file);
+	ostream = g_file_replace (doc->gfile,
+							  NULL /*etag*/,
+							  TRUE /*make backup*/,
+							  G_FILE_CREATE_NONE,
+							  NULL,
+							  NULL);
+	if(ostream) {
+		ret = hex_document_write_to_file(doc, G_OUTPUT_STREAM (ostream));
+		g_output_stream_close (G_OUTPUT_STREAM (ostream), NULL, NULL);
+		g_object_unref (ostream);
 		if(ret) {
 			doc->changed = FALSE;
 		}
@@ -751,7 +787,9 @@ hex_document_export_html(HexDocument *doc, gchar *html_path, gchar *base_name,
 						 guint cpw)
 {
 	GtkWidget *progress_dialog, *progress_bar;
-	FILE *file;
+	GFile *gfile;
+	GFileOutputStream *ofstream;
+	GDataOutputStream *odstream;
 	int page, line, pos, lines, pages, c;
 	gchar *page_name, b;
 	gint update_pages;
@@ -767,33 +805,75 @@ hex_document_export_html(HexDocument *doc, gchar *html_path, gchar *base_name,
 
 	/* top page */
 	page_name = g_strdup_printf("%s/%s.html", html_path, base_name);
-	file = fopen(page_name, "w");
+	gfile = g_file_new_for_path (page_name);
+	ofstream = g_file_replace (gfile,
+			NULL /*etag*/,
+			TRUE /*make backup*/,
+			G_FILE_CREATE_NONE,
+			NULL,
+			NULL);
 	g_free(page_name);
-	if(!file)
+	g_object_unref (gfile);
+	gfile = NULL;
+	if(!ofstream)
+		return FALSE;
+	odstream = g_data_output_stream_new (G_OUTPUT_STREAM (ofstream));
+	g_object_unref (ofstream);
+	if (!odstream)
 		return FALSE;
-	fprintf(file, "<HTML>\n<HEAD>\n");
-	fprintf(file, "<META HTTP-EQUIV=\"Content-Type\" "
-			"CONTENT=\"text/html; charset=UTF-8\">\n");
-	fprintf(file, "<META NAME=\"hexdata\" CONTENT=\"GHex export to HTML\">\n");
-	fprintf(file, "</HEAD>\n<BODY>\n");
-
-	fprintf(file, "<CENTER>");
-	fprintf(file, "<TABLE BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n");
-	fprintf(file, "<TR>\n<TD COLSPAN=\"3\"><B>%s</B></TD>\n</TR>\n",
-			doc->file_name?doc->file_name:doc->path_end);
-	fprintf(file, "<TR>\n<TD COLSPAN=\"3\">&nbsp;</TD>\n</TR>\n");
+	const gchar* header =
+		"<html>\n"
+		"<head>\n"
+		"<meta http-equiv=\"Content-Type\" "
+		"   content=\"text/html; charset=UTF-8\">\n"
+		"<meta name=\"hexdata\" content=\"GHex export to HTML\">\n"
+		"</head>\n<body>\n";
+	g_data_output_stream_put_string (odstream, header, NULL, NULL);
+
+	g_data_output_stream_put_string (odstream,
+			"<center>"
+			"<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"
+			"<tr>\n<td colspan=\"3\"><b>",
+			NULL, NULL);
+	
+	g_data_output_stream_put_string (odstream,
+			doc->file_name?doc->file_name:doc->path_end,
+			NULL, NULL);
+
+	g_data_output_stream_put_string (odstream,
+			"</b></td>\n</tr>\n"
+			"<tr>\n<td colspan=\"3\">&nbsp;</td>\n</tr>\n",
+			NULL, NULL);
+
 	for(page = 0; page < pages; page++) {
-		fprintf(file, "<TR>\n<TD>\n<A HREF=\"%s%08d.html\"><PRE>", base_name, page);
-		fprintf(file, _("Page"));
-		fprintf(file, " %d</PRE></A>\n</TD>\n<TD>&nbsp;</TD>\n<TD VALIGN=\"CENTER\"><PRE>%08x -", page+1, page*cpl*lpp);
-		fprintf(file, " %08x</PRE></TD>\n</TR>\n", MIN((page+1)*cpl*lpp-1, doc->file_size-1));
+		gchar* str = g_strdup_printf ("<tr>\n<td>\n<a href=\"%s%08d.html\"><pre>", base_name, page);
+		g_data_output_stream_put_string (odstream, str, NULL, NULL);
+		g_free (str);
+
+		g_data_output_stream_put_string (odstream, _("Page"), NULL, NULL);
+
+		str = g_strdup_printf (" %d</pre></a>\n</td>\n<td>&nbsp;</td>\n<td valign=\"center\"><pre>%08x -", page+1, page*cpl*lpp);
+		g_data_output_stream_put_string (odstream, str, NULL, NULL);
+		g_free (str);
+
+		str = g_strdup_printf (" %08x</pre></td>\n</tr>\n", MIN((page+1)*cpl*lpp-1, doc->file_size-1));
+		g_data_output_stream_put_string (odstream, str, NULL, NULL);
+		g_free (str);
 	}
-	fprintf(file, "</TABLE>\n</CENTER>\n");
-	fprintf(file, "<HR WIDTH=\"100%%\">");
-	fprintf(file, _("Hex dump generated by"));
-	fprintf(file, " <B>"LIBGTKHEX_RELEASE_STRING"</B>\n");
-	fprintf(file, "</BODY>\n</HTML>\n");
-	fclose(file);
+
+	g_data_output_stream_put_string (odstream,
+			"</table>\n</center>\n"
+			"<hr width=\"100%\">",
+			NULL, NULL);
+	g_data_output_stream_put_string (odstream,
+			_("Hex dump generated by"),
+			NULL, NULL);
+	g_data_output_stream_put_string (odstream,
+			" <b>"LIBGTKHEX_RELEASE_STRING"</b>\n"
+			"</body>\n</html>\n",
+			NULL, NULL);
+	g_output_stream_close (G_OUTPUT_STREAM (odstream), NULL, NULL);
+	g_object_unref (odstream);
 
 	progress_dialog = gtk_dialog_new();
 	gtk_window_set_resizable(GTK_WINDOW(progress_dialog), FALSE);
@@ -811,6 +891,7 @@ hex_document_export_html(HexDocument *doc, gchar *html_path, gchar *base_name,
 	pos = start;
 	g_object_ref(G_OBJECT(doc));
 	for(page = 0; page < pages; page++) {
+		char* str;
 		if((page%update_pages) == 0) {
 			gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar),
 										  (gdouble)page/(gdouble)pages);
@@ -824,101 +905,139 @@ hex_document_export_html(HexDocument *doc, gchar *html_path, gchar *base_name,
 		/* write page header */
 		page_name = g_strdup_printf("%s/%s%08d.html",
 									html_path, base_name, page);
-		file = fopen(page_name, "w");
+		gfile = g_file_new_for_path (page_name);
 		g_free(page_name);
-		if(!file)
+		ofstream = g_file_replace (gfile,
+				NULL /*etag*/,
+				TRUE /*make backup*/,
+				G_FILE_CREATE_NONE,
+				NULL,
+				NULL);
+		if(!ofstream)
 			break;
+		odstream = g_data_output_stream_new (G_OUTPUT_STREAM (ofstream));
+		g_object_unref (ofstream);
 		/* write header */
-		fprintf(file, "<HTML>\n<HEAD>\n");
-		fprintf(file, "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-1\">\n");
-		fprintf(file, "<META NAME=\"hexdata\" CONTENT=\"GHex export to HTML\">\n");
-		fprintf(file, "</HEAD>\n<BODY>\n");
+		g_data_output_stream_put_string (odstream, "<html>\n<head>\n"
+				"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n"
+				"<meta name=\"hexdata\" content=\"GHex export to HTML\">\n"
+				"</head>\n<body>\n", NULL, NULL);
 		/* write top table |previous|filename: page/pages|next| */
-		fprintf(file, "<TABLE BORDER=\"0\" CELLSPACING=\"0\" WIDTH=\"100%%\">\n");
-		fprintf(file, "<TR>\n<TD WIDTH=\"33%%\">\n");
+		g_data_output_stream_put_string(odstream,
+				"<table border=\"0\" cellspacing=\"0\" width=\"100%\">\n"
+				"<tr>\n<td width=\"33%\">\n",
+				NULL, NULL);
 		if(page > 0) {
-			fprintf(file, "<A HREF=\"%s%08d.html\">", base_name, page-1);
-			fprintf(file, _("Previous page"));
-			fprintf(file, "</A>");
+			str = g_strdup_printf ("<a href=\"%s%08d.html\">", base_name, page-1);
+			g_data_output_stream_put_string(odstream, str, NULL, NULL);
+			g_free (str);
+			g_data_output_stream_put_string(odstream, _("Previous page"), NULL, NULL);
+			g_data_output_stream_put_string(odstream, "</A>", NULL, NULL);
+		}
+		else {
+			g_data_output_stream_put_string(odstream,
+					"&nbsp;\n</td>\n"
+					"<td width=\"33%\" align=\"center\">\n", NULL, NULL);
 		}
-		else
-			fprintf(file, "&nbsp;");
-		fprintf(file, "\n</TD>\n");
-		fprintf(file, "<TD WIDTH=\"33%%\" ALIGN=\"CENTER\">\n");
-		fprintf(file, "<A HREF=\"%s.html\">", base_name);
-		fprintf(file, "%s:", doc->path_end);
-		fprintf(file, "</A>");
-		fprintf(file, " %d/%d", page+1, pages);
-		fprintf(file, "\n</TD>\n");
-		fprintf(file, "<TD WIDTH=\"33%%\" ALIGN=\"RIGHT\">\n");
+		str = g_strdup_printf ("<a href=\"%s.html\">%s</a>", base_name, doc->path_end);
+		g_data_output_stream_put_string (odstream, str, NULL, NULL);
+		g_free (str);
+		str = g_strdup_printf (" %d/%d", page+1, pages);
+		g_data_output_stream_put_string (odstream, str, NULL, NULL);
+		g_free (str);
+		g_data_output_stream_put_string (odstream,
+				"\n</td>\n"
+				"<td width=\"33%\" align=\"right\">\n",
+				NULL, NULL);
 		if(page < pages - 1) {
-			fprintf(file, "<A HREF=\"%s%08d.html\">", base_name, page+1);
-			fprintf(file, _("Next page"));
-			fprintf(file, "</A>");
+			str = g_strdup_printf ("<a href=\"%s%08d.html\">", base_name, page+1);
+			g_data_output_stream_put_string (odstream, str, NULL, NULL);
+			g_free (str);
+			g_data_output_stream_put_string (odstream, _("Next page"), NULL, NULL);
+			g_data_output_stream_put_string (odstream, "</a>", NULL, NULL);
+		}
+		else {
+			g_data_output_stream_put_string (odstream, "&nbsp;", NULL, NULL);
 		}
-		else
-			fprintf(file, "&nbsp;");
-		fprintf(file, "\n</TD>\n");
-		fprintf(file, "</TR>\n</TABLE>\n");
+		g_data_output_stream_put_string (odstream,
+				"\n</td>\n"
+				"</tr>\n</table>\n",
+				NULL, NULL);
 		
 		/* now the actual data */
-		fprintf(file, "<CENTER>\n");
-		fprintf(file, "<TABLE BORDER=\"1\" CELLSPACING=\"2\" CELLPADDING=\"2\">\n");
-		fprintf(file, "<TR>\n<TD>\n");
-		fprintf(file, "<TABLE BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n");
+		g_data_output_stream_put_string (odstream,
+				"<center>\n"
+				"<table border=\"1\" cellspacing=\"2\" cellpadding=\"2\">\n"
+				"<tr>\n<td>\n"
+				"<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n",
+				NULL, NULL);
 		for(line = 0; line < lpp && pos + line*cpl < doc->file_size; line++) {
 		/* offset of line*/
-			fprintf(file, "<TR>\n<TD>\n");
-			fprintf(file, "<PRE>%08x</PRE>\n", pos + line*cpl);
-			fprintf(file, "</TD>\n</TR>\n");
+			str = g_strdup_printf ("<tr>\n<td>\n<pre>%08x</pre>\n</td>\n</tr>\n", pos + line*cpl);
+			g_data_output_stream_put_string (odstream, str, NULL, NULL);
+			g_free (str);
 		}
-		fprintf(file, "</TABLE>\n");
-		fprintf(file, "</TD>\n<TD>\n");
-		fprintf(file, "<TABLE BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n");
+		g_data_output_stream_put_string (odstream,
+				"</table>\n"
+				"</td>\n<td>\n"
+				"<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n",
+				NULL, NULL);
 		c = 0;
 		for(line = 0; line < lpp; line++) {
 			/* hex data */
-			fprintf(file, "<TR>\n<TD>\n<PRE>");
+			g_data_output_stream_put_string (odstream, "<tr>\n<td>\n<pre>", NULL, NULL);
 			while(pos + c < end) {
-				fprintf(file, "%02x", hex_document_get_byte(doc, pos + c));
+				str = g_strdup_printf ("%02x", hex_document_get_byte(doc, pos + c));
+				g_data_output_stream_put_string (odstream, str, NULL, NULL);
+				g_free (str);
 				c++;
 				if(c%cpl == 0)
 					break;
 				if(c%cpw == 0)
-					fprintf(file, " ");
+					g_data_output_stream_put_string (odstream, " ", NULL, NULL);
 			}
-			fprintf(file, "</PRE>\n</TD>\n</TR>\n");
+			g_data_output_stream_put_string (odstream, "</pre>\n</td>\n</tr>\n", NULL, NULL);
 		}
-		fprintf(file, "</TABLE>\n");
-		fprintf(file, "</TD>\n<TD>\n");
-		fprintf(file, "<TABLE BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">\n");
+		g_data_output_stream_put_string (odstream,
+				"</table>\n"
+				"</td>\n<td>\n"
+				"<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n",
+				NULL, NULL);
 		c = 0;
 		for(line = 0; line < lpp; line++) {
 			/* ascii data */
-			fprintf(file, "<TR>\n<TD>\n<PRE>");
+			g_data_output_stream_put_string (odstream,
+					"<tr>\n<td>\n<pre>",
+					NULL, NULL);
 			while(pos + c < end) {
 				b = hex_document_get_byte(doc, pos + c);
-				if(b >= 0x20)
-					fprintf(file, "%c", b);
-				else
-					fprintf(file, ".");
+				if(b >= 0x20) {
+					str = g_strdup_printf ("%c", b);
+					g_data_output_stream_put_string (odstream, str, NULL, NULL);
+					g_free (str);
+				} else {
+					g_data_output_stream_put_string (odstream, ".", NULL, NULL);
+				}
 				c++;
 				if(c%cpl == 0)
 					break;
 			}
-			fprintf(file, "</PRE></TD>\n</TR>\n");
+			g_data_output_stream_put_string (odstream, "</pre></td>\n</tr>\n", NULL, NULL);
 			if(pos >= end)
 				line = lpp;
 		}
 		pos += c;
-		fprintf(file, "</TD>\n</TR>\n");
-		fprintf(file, "</TABLE>\n");
-		fprintf(file, "</TABLE>\n</CENTER>\n");
-		fprintf(file, "<HR WIDTH=\"100%%\">");
-		fprintf(file, _("Hex dump generated by"));
-		fprintf(file, " <B>" LIBGTKHEX_RELEASE_STRING "</B>\n");
-		fprintf(file, "</BODY>\n</HTML>\n");
-		fclose(file);
+		g_data_output_stream_put_string (odstream,
+				"</td>\n</tr>\n"
+				"</table>\n"
+				"</table>\n</center>\n"
+				"<hr width=\"100%\">"
+				"Hex dump generated by"
+				" <b>" LIBGTKHEX_RELEASE_STRING "</b>\n"
+				"</body>\n</html>\n",
+				NULL, NULL);
+		g_output_stream_close (odstream, NULL, NULL);
+		g_object_unref (odstream);
 	}
 	g_object_unref(G_OBJECT(doc));
 	gtk_widget_destroy(progress_dialog);
diff --git a/src/hex-document.h b/src/hex-document.h
index 39368ed..52acddd 100644
--- a/src/hex-document.h
+++ b/src/hex-document.h
@@ -28,6 +28,7 @@
 #include <gtk/gtkwidget.h>
 
 #include <glib-object.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -61,6 +62,7 @@ struct _HexDocument
 
 	GList *views;      /* a list of GtkHex widgets showing this document */
 	
+	GFile *gfile;
 	gchar *file_name;
 	gchar *path_end;
 
@@ -105,7 +107,7 @@ void        hex_document_delete_data(HexDocument *doc, guint offset,
 									 guint len, gboolean undoable);
 gint        hex_document_read(HexDocument *doc);
 gint        hex_document_write(HexDocument *doc);
-gint        hex_document_write_to_file(HexDocument *doc, FILE *file);
+gint        hex_document_write_to_file(HexDocument *doc, GOutputStream *ostream);
 gint        hex_document_export_html(HexDocument *doc,
 									 gchar *html_path, gchar *base_name,
 									 guint start, guint end,
@@ -126,6 +128,7 @@ void        hex_document_remove_view(HexDocument *doc, GtkWidget *view);
 GtkWidget   *hex_document_add_view(HexDocument *doc);
 const GList *hex_document_get_list(void);
 gboolean    hex_document_is_writable(HexDocument *doc);
+void        hex_document_set_filename (HexDocument* doc, const gchar *name);
 
 G_END_DECLS
 
