Re-writing to a config file becomes gibberish

I'm trying to write a wallpaper shuffling system (here is the git repo). With my algorithm to reading then writing to the file, it seems to start appending gibberish when re-writing the contents of the file after it removes the first.

Here is the general breakdown of what I want this to do:

  1. Read in directory of pictures recursively. (done)
  2. Write a list of pictures with their full paths line by line in the config file. (done)
  3. Read the config file, return a random value, remove that value from the config file, then save the config file. (This is what is outlined below in a simplified way).

Say the contents of test.txt has this:

./testing/more-wallpapers/1/testing.png
./testing/more-wallpapers/3/test.png
./testing/more-wallpapers/lol.png
./testing/more-wallpapers/1/lmao.jpeg
./testing/more-wallpapers/1/lmao.jpg
./testing/lol.bmp
./testing/more-wallpapers/2/x9870979038.png
./testing/more-wallpapers/2/eaotuhnsoeushtnaoeuhtns.png
use std::fs;
use std::io;
use std::io::{Write,Read,Seek,BufReader,BufRead};
use std::path::Path;

fn main() -> io::Result<()> {
    // specify the path to the file
    let file_path = Path::new("./test.txt");
    
    // open the file in read-write mode
    let rfile = fs::OpenOptions::new()
        .read(true)
        .write(false)
        .open(file_path)?;

    let wfile = fs::OpenOptions::new()
        .read(false)
        .write(true)
        .open(file_path)?;

    let mut reader = io::BufReader::new(rfile);
    let mut writer = io::BufWriter::new(wfile);

    // read the first line from the file
    let mut first_line = String::new();
    reader.read_line(&mut first_line)?;
    println!("{first_line}");

    // write the remaining lines to the file, skipping the first line
    let mut lines = String::new();
    reader.read_to_string(&mut lines)?;
    dbg!(&lines);
    writer.write_all(lines.as_bytes())?;

    Ok(())
}

Running this a few times, it starts to make the text gibberish like this:

ers/2/eaotuhnsoeushtnaoeuhtns.png
png
ers/2/eaotuhnsoeushtnaoeuhtns.png
ng
ers/2/eaotuhnsoeushtnaoeuhtns.png
ushtnaoeuhtns.png
otuhnsoeushtnaoeuhtns.png
ushtnaoeuhtns.png
oeuhtns.png
otuhnsoeushtnaoeuhtns.png
ushtnaoeuhtns.png
nsoeushtnaoeuhtns.png
ushtnaoeuhtns.png
eushtnaoeuhtns.png
ushtnaoeuhtns.png

I'm just confused why this is happening and how I should go about fixing it.

The file is not automatically truncated to the length that you wrote to it. It still has the previous contents, past the part that you wrote. You can call set_len() to update the length after you finish writing.

Also, while it will work as intended with that fix, it's not ideal to open the file twice. You should open it just once, and you can use BufReader::into_inner() to get the File back out once you're done reading (among other options).

5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.