diff --git a/src/xdmf.jl b/src/xdmf.jl
index 7ab0d11687d829d0f08a29e1df2da9ac252a14af..bdfd06c0de1c5f5ca4acb3e13d3a478a254ecda7 100644
--- a/src/xdmf.jl
+++ b/src/xdmf.jl
@@ -4,6 +4,7 @@ const XDMF_END = """
 """
 
 mutable struct XDMFOutput
+    buffer::IOBuffer
     dir::String
     h5_filename::String
     mesh_filename::String
@@ -25,7 +26,9 @@ function XDMFOutput(dir)
     open(mesh_filename, "w") do file
     end
 
-    return XDMFOutput(dir, h5_filename, mesh_filename, 0, 0)
+    buffer = IOBuffer()
+
+    return XDMFOutput(buffer, dir, h5_filename, mesh_filename, 0, 0)
 end
 
 
@@ -35,21 +38,20 @@ function xdmfwrite_mesh(xdmf::XDMFOutput, mesh::Mesh)
         throw(ArgumentError("Mesh has already been write"))
     end
 
-    buffer = IOBuffer()
-    write_mesh_header(buffer)
+    # buffer = IOBuffer()
+    write_mesh_header(xdmf.buffer)
 
     # Using "w" here to overwrite in case previous calls failed
     h5open(xdmf.h5_filename, "w") do file
-        write_mesh(file, buffer, mesh)
+        write_mesh(file, xdmf.buffer, mesh)
     end
 
-    write_mesh_end(buffer)
+    write_mesh_end(xdmf.buffer)
 
     # finish up xml files
     # Using "w" here to overwrite in case previous calls failed
     open(xdmf.mesh_filename, "a") do file
-        seekstart(buffer)
-        write(file, buffer)
+        write(file, take!(xdmf.buffer))
     end
 
     # updating count after all writes succeeded
@@ -59,13 +61,14 @@ end
 
 
 function write_mesh_header(buffer)
-    write(buffer, """
+    print(buffer, """
 <?xml version="1.0" ?>
 <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
 <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="3.0">
 <Domain>
 <Grid GridType="Collection" CollectionType="Spatial">
 """)
+    return
 end
 
 
@@ -131,61 +134,67 @@ size3d(sz::NTuple{2}) = (sz[1],sz[2],1)
 # size3d(sz::NTuple{3}) = (sz[1],sz[2],sz[3])
 
 
-function xdmfwrite_scalar(xdmf::XDMFOutput, mesh::Mesh, t, vars, names)
+function write_scalar(h5, buffer, mesh::Mesh, dir, tcount, t, var, name)
 
-    buffers = IOBuffer[]
-    for _ in vars
-        b = IOBuffer()
-        write(b, """
+    write(buffer, """
 <Grid GridType="Collection" CollectionType="Temporal"><Grid GridType="Collection" CollectionType="Spatial">
 <Time Value="$t"/>
 """)
-        push!(buffers, b)
-    end
 
-    tcount = xdmf.tcount + 1
-    celliters = [ eachcell(mesh, var) for var in vars ]
-    h5open(xdmf.h5_filename, "r+") do h5
-
-        # an other group the new time step
-        h5group_t = create_group(h5, string(tcount))
-        # sub groups for each mesh
-        groups = [ create_group(h5group_t, string(i)) for i = 1:ncells(mesh) ]
-
-        for (cellit, name, buffer) in zip(celliters, names, buffers)
-            for (i,(cellvar,g)) in enumerate(zip(cellit,groups))
-                nx, ny, nz = size3d(size(cellvar))
-                g[name] = view(cellvar,:)
-                write(buffer, """
+    variter = eachcell(mesh, var)
+
+    # a group to gather grids from one time step
+    tgroup = create_group(h5, string(tcount))
+
+    for (i,v) in enumerate(variter)
+        nx, ny, nz = size3d(size(v))
+        g = create_group(tgroup, string(i))
+        g[name] = v
+        write(buffer, """
 <Grid Name="$i"><xi:include href="mesh.xdmf" xpointer="xpointer(/Xdmf/Domain/Grid[1]/Grid[$i]/child::*)"/><Attribute Name="$name"><DataItem Dimensions="$nz $ny $nx" Format="HDF"> data.h5:/$tcount/$i/$name </DataItem></Attribute></Grid>
 """)
-            end
-            write(buffer, "</Grid></Grid>")
-        end
     end
 
-    # finish up xml files
-    for (buffer,name) in zip(buffers,names)
-        filename = joinpath(xdmf.dir, "$name.xdmf")
-        existed = isfile(filename)
-        open(filename, "a") do file
-            if !existed
-                print(file, """
+    write(buffer, "</Grid></Grid>")
+
+    filename = joinpath(dir, "$name.xdmf")
+    existed = isfile(filename)
+    open(filename, "a") do file
+        if !existed
+            print(file, """
 <?xml version="1.0" ?>
 <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
 <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="3.0">
 <Domain>
 """)
-            else
-                skip(file, -length(XDMF_END))
-            end
-            seekstart(buffer)
-            write(file, buffer)
-            write(file, XDMF_END)
+        else
+            skip(file, -length(XDMF_END))
+        end
+        write(file, take!(buffer))
+        write(file, XDMF_END)
+    end
+
+    return
+end
+
+function xdmfwrite_scalar(xdmf::XDMFOutput, mesh::Mesh, t, vars, names)
+
+    tcount = xdmf.tcount + 1
+    h5 = h5open(xdmf.h5_filename, "r+")
+
+    try
+        for (var, name) in zip(vars, names)
+            write_scalar(h5, xdmf.buffer, mesh, xdmf.dir, tcount, t, var, name)
         end
+    catch e
+        rethrow(e)
+    finally
+        close(h5)
     end
 
     # updating count after all writes succeeded
     xdmf.tcount = tcount
 
+    return
+
 end