gpt4 book ai didi

rust - 注意文件删除和重新创建

转载 作者:行者123 更新时间:2023-12-03 11:33:40 26 4
gpt4 key购买 nike

我在BufReader上有一个File。我使用read_line从文件中读取。这以固定的速率(例如每五秒钟)进行。在这五秒钟之内,可能会删除文件并使用相同的名称重新创建该文件。不幸的是,文件和阅读器对象仍然保留了对旧的未链接文件的引用,并成为了僵尸。
MVCE:

use std::fs::File;
use std::io::{BufRead, BufReader};
use std::{thread, time};

fn main() -> std::io::Result<()> {
let mut x = String::new();

let f = File::open("foo.txt")?;
let mut reader = BufReader::new(&f);
let metadata = f.metadata()?;

let res = reader.read_line(&mut x);
println!("First: {:?}\n{:?}\n{:?}", metadata, x, res);

let duration = time::Duration::from_millis(5000);
thread::sleep(duration);
// delete the file in this time

let metadata = f.metadata()?;
let res = reader.read_line(&mut x);
println!("Second: {:?}\n{:?}\n{:?}", metadata, x, res);

Ok(())
}
我得到的输出是:
First: Metadata { file_type: FileType(FileType { mode: 33204 }), is_dir: false, is_file: true, permissions: Permissions(FilePermissions { mode: 33204 }), modified: Ok(SystemTime { tv_sec: 1610027798, tv_nsec: 326270377 }), accessed: Ok(SystemTime { tv_sec: 1610027788, tv_nsec: 510393797 }), created: Ok(SystemTime { tv_sec: 1610027786, tv_nsec: 622417600 }) }
"1\n"
Ok(2)
Second: Metadata { file_type: FileType(FileType { mode: 33204 }), is_dir: false, is_file: true, permissions: Permissions(FilePermissions { mode: 33204 }), modified: Ok(SystemTime { tv_sec: 1610027798, tv_nsec: 326270377 }), accessed: Ok(SystemTime { tv_sec: 1610027801, tv_nsec: 298233116 }), created: Ok(SystemTime { tv_sec: 1610027786, tv_nsec: 622417600 }) }
"1\n"
Ok(0)
如您所见,这两个时间戳是相同的,并且没有迹象表明基础File对象已经与主文件系统解除链接。 corresponding Python question使用 os.fstat,但是我不知道如何使用相应的Rust替代项(我认为是 is this)。
我每五秒钟的一般算法是:
  • 使用fstat查找当前打开的File对象的 Activity 链接数。
  • 如果链接数为零,请重新打开File对象。
  • 如果链接数仍然为零,请在五秒钟后继续执行步骤1。
  • 来自此文件的Read_line。

  • 我很乐意帮助您弄清楚如何执行步骤1,或者是否有完全不同的方法来执行此步骤。

    最佳答案

    标准库确实具有用于获取链接数量的方法。它们只是隐藏在特定于OS的扩展程序后面。
    存在三种MetadataExt特征,每个特征在 std::os::linux::fs std::os::unix::fs std::os::windows::fs 中。每个都有各自的 st_nlink() nlinks() number_of_links() 。注意Windows的是实验性的。
    另外,您也可以使用 notify crate监视文件事件。

    Unix:

    use std::os::unix::fs::MetadataExt;

    use std::fs::File;
    use std::thread;
    use std::time::Duration;

    fn main() {
    let f = File::open("foo.txt").unwrap();

    println!("{:?}", f.metadata().unwrap().nlinks());
    // Prints `1`

    // Now delete `foo.txt`
    thread::sleep(Duration::from_secs(5));

    println!("{:?}", f.metadata().unwrap().nlinks());
    // Prints `0`
    }

    Windows:
    #![feature(windows_by_handle)]

    use std::os::windows::fs::MetadataExt;

    use std::fs::File;
    use std::thread;
    use std::time::Duration;

    fn main() {
    let f = File::open("foo.txt").unwrap();

    println!("{:?}", f.metadata().unwrap().number_of_links());
    // Prints `Some(1)`

    // Now delete `foo.txt`
    thread::sleep(Duration::from_secs(5));

    println!("{:?}", f.metadata().unwrap().number_of_links());
    // Prints `Some(0)`
    }

    关于rust - 注意文件删除和重新创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65613880/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com