I have a file foo.txt
with the content
foobar
I want to continuously append to this file and have access to the modified file.
MmapMut
The first thing I tried is to mutate the mmap directly:
use memmap;
use std::fs;
use std::io::prelude::*;
fn main() -> Result<(), Box<std::error::Error>> {
let backing_file = fs::OpenOptions::new()
.read(true)
.append(true)
.create(true)
.write(true)
.open("foo.txt")?;
let mut mmap = unsafe { memmap::MmapMut::map_mut(&backing_file)? };
loop {
println!("{}", std::str::from_utf8(&mmap[..])?);
std::thread::sleep(std::time::Duration::from_secs(5));
let buf = b"somestring";
(&mut mmap[..]).write_all(buf)?;
mmap.flush()?;
}
}
This will result in a panic:
Error: Custom { kind: WriteZero, error: StringError("failed to write whole buffer") }
The resulting file reads somest
Appending to the backing file directly
After that, I tried to append to the backing file directly:
use memmap;
use std::fs;
use std::io::prelude::*;
fn main() -> Result<(), Box<std::error::Error>> {
let mut backing_file = fs::OpenOptions::new()
.read(true)
.append(true)
.create(true)
.write(true)
.open("foo.txt")?;
let mmap = unsafe { memmap::MmapMut::map_mut(&backing_file)? };
loop {
println!("{}", std::str::from_utf8(&mmap[..])?);
std::thread::sleep(std::time::Duration::from_secs(5));
let buf = b"somestring";
backing_file.write_all(buf)?;
backing_file.flush()?;
}
}
This does not result in a panic. The file will get updated regularly, but my mmap does not reflect these changes. I expected standard output to look like this:
foobar
foobarsomestring
foobarsomestringsomestring
...
But I got
foobar
foobar
foobar
...
I am mainly interested in a Linux solution if it is platform-dependent.