Read then write to same file for code (text file) formatting

I want to sort a TOML file content (I know TOML does not ensure its ordering but let’s put it aside). So, I write the following script try to read a TOML file then sort by keys and then replace it by sorted TOML file. But "r+" and "w+" options don’t work well.

using TOML
using OrderedCollections

function sortfile(filename)
    open(filename, "r+") do io
        unordered = TOML.parse(io)
        ordered = OrderedDict(sort(collect(unordered), by=x->x[1]))
        TOML.print(io, ordered)
    end
end

# sort by keys
sortfile("sample.toml")

Generally, what kind of processing is recommended for such work?

First read the file and close it, then write it.

I use:

function readfile(filename)
    open(filename) do file
        readlines(file)
    end
end

function writefile(lines, filename)
    open(filename, "w") do file
        for line in lines
            write(file, line, '\n')
        end
    end
end

DaveMacMahon taught me I need seekstart(io) and truncate(io, position(io)) before TOML.print.

using TOML
using OrderedCollections

function sortfile(filename)
    open(filename, "r+") do io
        unordered = TOML.parse(io)
        OrderedDict(unordered)
        ordered = OrderedDict(sort!(collect(unordered), by=first))
        seekstart(io)
        truncate(io, position(io))
        TOML.print(io, ordered)
    end
end

# sort by keys
sortfile("sample.toml")
1 Like

Thanks, but I want to do it only opening file once.

Is opening files very slow for you or do you just not want to call open twice? If it’s the latter you can hide the opening for reading with

function sortfile(filename)
    unordered = TOML.parsefile(filename)
    ordered = OrderedDict(sort!(collect(unordered), by=first))
    open(filename, "w") do io
        TOML.print(io, ordered)
    end
end

Your question was what kind of processing is recommended. I would say that it is recommended that, while reading from file A, you write into a temporary file B. Once you are done writing (and everything succeeded) you rename B to A.

1 Like