In the second snippet, buf’s size is always 4096, so if n < 4096 then the first element becomes the element at index 4095 after reverse!, not index n - 1. I believe all you need to do is:
loop do
buf = Slice(UInt8).new(4096)
n = infile.read(buf)
break if n == 0
outfile.write(buf[0...n].reverse!)
end