print to an IOBuffer. (This is what string does internally anyway.) For even more re-use, you can make a non-destructive String-like view of an IOBuffer with StringViews.jl.
Should be better still to ditch the string and join calls entirely and just print directly to the file, e.g. something like:
function to_file(v, filename)
open(filename, "w") do file
println(file, 0)
for (i, val) in pairs(v)
println(file, i, ':', val)
end
end
end
(which is also more readable than the join version in my opinion). Note that I use print instead of write to output the text representations of i and val directly. You could also use enumerate instead of pairs to allow v to be an iterator rather than a vector (and to guarantee that the output indices start at 1).
A version of this idea is also in the Julia performance tips (“Avoid string interpolation for I/O”): don’t construct an intermediate string just to write it to a file.