Enumerate output file names

This weekend I plan on working on and get basic understanding OsStr and std::path. This time I will ask before trying to figure it out myself.

I have a PathBuf and a loop counter in my clap struct.

    /// Save Ok as
    ///
    /// File name without hex or number added
    save_ok_as: Option<std::path::PathBuf>,

    /// The loop count
    #[clap(skip)]
    loop_count: usize,

My struct is in a struct and the implementation has some access functions.

    fn save_ok_as(&self) -> &Option<std::path::PathBuf> {
        &self.controls_as_ref().save_ok_as
    }
    fn loop_count(&self) -> usize {
        self.controls_as_ref().loop_count
    }

In a loop I would like to save blocks of bytes to files. I would like to have my file names have a number added to the end.

file00001
file00002
...

I read docs, but haven't played with changing file names. I know I will probably have to get an owned OsString from the PathBuf, but do I do that every loop. Seems like a lot of string creations, if I loop and make a thousand files. But of course that is minimal to writing a thousand files.

What is the "idiomatic" ? way to write many files with numbers added to the file name. Of course the numbers should be zero padded so sorting and listing is neater.

Thanks in advance for making my upcoming Saturday easier.

  /// in my loop....self is the clap stuct's holder struct.
  if let Some(path) = self.save_ok_as() {
      // I want to add number from self.loop_count()
      // to the end of file name before I create each file.
      match std::fs::File::create(path) {

You could try reusing buffers to store the extended paths:

use std::{
    fmt::Write,
    fs::File,
    path::{Path, PathBuf},
};
// outside loop:
let mut suffix = String::new();
let mut ext_path = PathBuf::new();
// inside loop:
if let Some(path) = self.save_ok_as() {
    suffix.clear();
    write!(suffix, "{:05}", self.loop_count()).unwrap();
    ext_path.clear();
    ext_path.push(path);
    ext_path.push(suffix);
    match File::create(ext_path) {
        _ => unimplemented!(),
    }
}
1 Like

Thank you, but yes I did try push()
PathBuf push() puts things in a deeper directory, it doesn't just add the file name, as can be seen by this playground..

Ah, you're right; I'll admit, I didn't try the code myself. Luckily, it can be easily fixed by making ext_path an OsString instead of a PathBuf (Rust Playground):

// outside loop:
let mut suffix = String::new();
let mut ext_path = OsString::new();
// inside loop:
if let Some(path) = self.save_ok_as() {
    suffix.clear();
    write!(suffix, "{:05}", self.loop_count()).unwrap();
    ext_path.clear();
    ext_path.push(path);
    ext_path.push(suffix);
    match File::create(ext_path) {
        /* ... */
    }
}

OsString.push("string") is the function I needed.
Thank you so much.

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.