Stream: helpdesk (published)

Topic: How to make sure write(io, string) always writes N bytes?


view this post on Zulip Júlio Hoffimann (Dec 04 2025 at 14:46):

I need to make sure that the number of bytes written to the file is always N, regardless of the content of the string. What is the most idiomatic method to achieve that goal with the Julia IO stdlib?

view this post on Zulip Gunnar Farnebäck (Dec 04 2025 at 15:13):

What do you want to happen when the string representation is shorter or longer than N bytes?

view this post on Zulip Júlio Hoffimann (Dec 04 2025 at 15:23):

If it is shorter, we could append some special character that is not visible when decoding the bytes in a posterior read. Like a null character.

view this post on Zulip Júlio Hoffimann (Dec 04 2025 at 15:24):

If it is longer, I will throw an error. We can ignore this case.

view this post on Zulip Vincent Laporte (Dec 04 2025 at 15:46):

There is a truncate function in Base that sounds related.

view this post on Zulip Júlio Hoffimann (Dec 04 2025 at 15:48):

Nice. It seems very related indeed.

view this post on Zulip Júlio Hoffimann (Dec 04 2025 at 15:49):

We need something like that, but for writing into an IO as opposed to modifying the content of an existing IO with the string.

view this post on Zulip Júlio Hoffimann (Dec 04 2025 at 15:51):

From the docstring, it uses '\0' as the null character.

view this post on Zulip Gunnar Farnebäck (Dec 04 2025 at 15:53):

You can do things like

function padded_write(io::IO, args...; N)
    n = write(io, args...)
    write(io, fill(0x00, N - n))
end

function close_with_padding(io::IO, N)
    n = position(io)
    write(io, fill(0x00, N - n))
    close(io)
end

but truncate is almost certainly better.

view this post on Zulip Nathan Zimmerberg (Dec 04 2025 at 15:58):

One option is to create a vector of N zero UInt8 as a buffer, copy in the string data, write out with write, and then finally error if write doesn't return N.

view this post on Zulip Nathan Zimmerberg (Dec 04 2025 at 16:01):

Avoid position function when writing as some IO do not have this implemented in the way you would think

view this post on Zulip Júlio Hoffimann (Dec 04 2025 at 16:11):

So if I want to use truncate, I need to create an empty IO, copy the string there, call truncate and then finally write to the final IO that corresponds to the file on disk? Something like the following:

io = IOBuffer()
write(io, string)
truncate(io, N)
newstring = read(io, N)
write(iofinal, newstring)

view this post on Zulip Júlio Hoffimann (Dec 04 2025 at 16:13):

The padded_write function seems more intuitive.

view this post on Zulip Nathan Zimmerberg (Dec 04 2025 at 16:29):

Yeah, ideally the underlying IO interface would support this like zig now does with the splat argument in https://ziglang.org/documentation/master/std/#std.Io.Writer.VTable but currently IO goes through unsafe_write which just takes a pointer and a size.

I do
https://github.com/JuliaIO/ZipArchives.jl/blob/c48c367b6208c9733ff0e2f3431a6b8d13939126/src/writer.jl#L253

view this post on Zulip Gunnar Farnebäck (Dec 04 2025 at 17:01):

Why can't you just do truncate(iofinal, N) once you have written what you want to it?

view this post on Zulip Júlio Hoffimann (Dec 04 2025 at 17:50):

I could do that in this case I think. Will try it.

view this post on Zulip Jakob Nybo Andersen (Dec 04 2025 at 17:53):

Write a view of the string. For the padding, I don't think we have any good abstractions for that.
Another good reason for my BufferIO.jl where this can be done efficiently and allocation free :wink:


Last updated: Dec 18 2025 at 04:52 UTC