Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何替换.txt文件中的单词_Rust - Fatal编程技术网

Rust 如何替换.txt文件中的单词

Rust 如何替换.txt文件中的单词,rust,Rust,我想打开一个文件,只替换其中的一个单词。除了用新文本创建一个新文件外,我似乎找不到任何方法来实现这一点 文件是一个字节序列。出于性能原因,文件几乎总是占用硬盘上的一大块空间。从程序员的角度来看,操作连续文件也更容易,因为在这种情况下,文件可以看作是一个普通数组;否则,应该有一些类似链表或树的数据结构,在99%的情况下,这只会使编程更加困难。因此,可以很容易地添加文件,但是在中间插入或删除数据更为困难。这通常分五个步骤完成(对于插入;移除非常类似): 创建新的临时文件(或者,如果文件大小适中,则在

我想打开一个文件,只替换其中的一个单词。除了用新文本创建一个新文件外,我似乎找不到任何方法来实现这一点

文件是一个字节序列。出于性能原因,文件几乎总是占用硬盘上的一大块空间。从程序员的角度来看,操作连续文件也更容易,因为在这种情况下,文件可以看作是一个普通数组;否则,应该有一些类似链表或树的数据结构,在99%的情况下,这只会使编程更加困难。因此,可以很容易地添加文件,但是在中间插入或删除数据更为困难。这通常分五个步骤完成(对于插入;移除非常类似):

  • 创建新的临时文件(或者,如果文件大小适中,则在内存中创建缓冲区)
  • 将插入点之前的所有内容复制到此新文件
  • 将新数据写入此新文件或
  • 将插入点之后的所有内容复制到新文件
  • 复制完所有内容后,将移动临时文件以替换原始文件
  • 替换长度可能不同的单词通常包括删除或插入。对于大小合适的文件,最简单的方法是将整个源文件读入内存,对其运行替换操作,并将结果转储回原始文件。这样,项目2-4将由字符串操作的库代码自动完成。下面是一个示例程序(它从命令行参数获取源字、替换字和文件路径):

    使用std::env;
    使用std::fs::File;
    使用std::io::{self,Read,Write};
    使用std::path::path;
    fn main(){
    //处理错误
    运行().unwrap();
    }
    fn run()->结果{
    //从命令行参数中提取单词和文件路径
    让args:Vec=env::args().skip(1.collect();
    如果args.len()!=3{
    println!(“参数数目错误”);
    返回Ok(());
    }
    让单词_from=&args[0];
    //如果源字为空,则无需替换
    如果单词_from.is_empty(){返回Ok(());}
    让单词_to=&args[1];
    让文件名=&args[2];
    让file\u path=path::new(&file\u name);
    //打开并完全读取文件
    让mut src=File::open(&File_路径)?;
    让mut data=String::new();
    src.read_to_字符串(&mut数据)?;
    drop(src);//提前关闭文件
    //在内存中运行replace操作
    让new_data=data.replace(&*word_from,&*word_to);
    //重新创建文件并将处理过的内容转储到其中
    让mut dst=File::create(&File_path)?;
    写入(新的_数据作为_字节())?;
    println!(“完成”);
    好(())
    }
    
    请注意,创建临时文件仍然是一个好主意,因为将大量数据写入文件不是一个原子操作,而重命名文件通常是一个原子操作。因此,如果出现问题,并且您不使用临时文件,那么您的源文件可能会损坏。如果使用临时文件,则源文件将被完全替换或不替换


    如果您的文件很大(也就是说,几GB或更大),流式替换可能是一个好主意。在这种情况下,您需要以块的形式读取文件(低至1字节长度,这可能会更容易),并在这些块中运行replace操作,将结果写入临时文件。处理完整个源文件后,临时文件将移到源文件上。如果你读的是大于单字节的块,你还需要处理单词在这些块之间“分割”的情况。

    你的问题有点。。。缺乏细节。我理解,你想用一个词替换另一个词,但是:替换词的长度相同吗?还是不?2/是否要说明各种拼写或编码?3/要替换第一个事件还是所有事件?--请注意,(1)是最重要的,因为如果需要更改字长,则很可能需要复制文件(尽管可以在内存中复制)并完全替换其内容,以便适当扩展或不留间隙。注意:直接编辑您问题中的详细信息。1/否替换内容的长度不同2/否,我需要一个特定的名称3/我想知道两种方法,但我需要的是所有发生的编码是什么?你知道这个文件的编码吗?如果是ASCII码,则比必须使用Unicode码(单个“字”可以使用不同的字节表示法)要容易得多。是的,它是ASCII码。另外,是否需要复制文件?我正在处理的文件有14k行长,我试着复制文本,但这并不方便。我恐怕你别无选择,想象一下:“敏捷的棕色狐狸跳过了懒狗”并将“狐狸”替换为“大象”=>“敏捷的棕色大象超过了懒狗”并不是你想要的,是吗?因此,您需要复制“fox”之后的所有内容,以便为“phant”腾出空间。重命名注意:如果要重命名的文件位于同一卷上,则重命名可以是原子的。如果在
    /tmp
    中创建临时文件,它可能与原始文件不在同一卷上,此时重命名实际上是复制,然后删除。当然,这并不是说对单个文件的并发操作,这是一个令人毛骨悚然的话题。@MatthieuM.,是的,当然,你是对的,但是,我认为如果这种复制发生在底层库或操作系统本身中,比在用户代码中更可靠。在这种情况下,失败点就更少了。
    use std::env;
    use std::fs::File;
    use std::io::{self, Read, Write};
    use std::path::Path;
    
    fn main() {
        // Handle errors
        run().unwrap();
    }
    
    fn run() -> Result<(), io::Error> {
        // Extract words and file path from the command line args
        let args: Vec<String> = env::args().skip(1).collect();
        if args.len() != 3 {
            println!("Wrong number of arguments");
            return Ok(());
        }
    
        let word_from = &args[0];
        // If the source word is empty then there is nothing to replace
        if word_from.is_empty() { return Ok(()); }  
    
        let word_to = &args[1];
    
        let file_name = &args[2];
        let file_path = Path::new(&file_name);
    
        // Open and read the file entirely
        let mut src = File::open(&file_path)?;
        let mut data = String::new();
        src.read_to_string(&mut data)?;
        drop(src);  // Close the file early
    
        // Run the replace operation in memory
        let new_data = data.replace(&*word_from, &*word_to);
    
        // Recreate the file and dump the processed contents to it
        let mut dst = File::create(&file_path)?;
        dst.write(new_data.as_bytes())?;
    
        println!("done");
    
        Ok(())
    }