我想读取一个文件,删除所有重复项并将其余部分写回文件 - 就像一个重复的清理器。 Vec因为普通数组的大小固定但我的.txt很灵活(我这样做了吗?)。
阅读,Vec中的行+删除重复项: 缺少回写文件。
use std::io;
fn main() {
let path = Path::new("test.txt");
let mut file = io::BufferedReader::new(io::File::open(&path, R));
let mut lines: Vec<String> = file.lines().map(|x| x.unwrap()).collect();
// dedup() deletes all duplicates if sort() before
lines.sort();
lines.dedup();
for e in lines.iter() {
print!("{}", e.as_slice());
}
}
读取+写入文件(未经测试但应该可以工作)。 缺少Vec的行,因为它似乎没有BufferedReader工作(或者我做了别的错误,也是一个很好的机会)。
use std::io;
fn main() {
let path = Path::new("test.txt");
let mut file = match io::File::open_mode(&path, io::Open, io::ReadWrite) {
Ok(f) => f,
Err(e) => panic!("file error: {}", e),
};
let mut lines: Vec<String> = file.lines().map(|x| x.unwrap()).collect();
lines.sort();
// dedup() deletes all duplicates if sort() before
lines.dedup();
for e in lines.iter() {
file.write("{}", e);
}
}
那么......我怎么把这两个人放在一起? :)
答案 0 :(得分:2)
最终,您将遇到一个问题:您正在尝试写入您正在阅读的同一文件。在这个的情况下,它是安全的,因为您将要阅读整个文件,因此您之后就不需要它了。但是,如果确实尝试写入文件,那么实际上你最后会写它!这是执行此操作的代码:
use std::io;
fn main() {
let path = Path::new("test.txt");
let file = match io::File::open_mode(&path, io::Open, io::ReadWrite) {
Ok(f) => f,
Err(e) => panic!("file error: {}", e),
};
let mut reader = io::BufferedReader::new(file);
let mut lines: Vec<String> = reader.lines().map(|x| x.unwrap()).collect();
lines.sort();
lines.dedup();
let mut file = reader.into_inner();
for line in lines.iter() {
file.write_str(line.as_slice());
}
}
密钥是对into_inner
的调用,它返回原始文件。这是输出:
$ cat test.txt
a
a
b
a
$ ./dedup
$ cat test.txt
a
a
b
a
a
b
您可以将文件指针重置回到开头,但是您可能会在结尾处留下尾随的东西(重复数据删除可能比写入更少写入字节)。重新打开文件进行写入会更容易,这将截断文件。另外,让我们使用设置数据结构为我们执行重复数据删除!
use std::io;
use std::collections::HashSet;
fn read(path: &Path) -> HashSet<String> {
let file = match io::File::open(path) {
Ok(f) => f,
Err(e) => panic!("file error: {}", e),
};
let mut reader = io::BufferedReader::new(file);
reader.lines().map(|x| x.unwrap()).collect()
}
fn write(path: &Path, mut lines: HashSet<String>) {
let mut file = match io::File::open_mode(path, io::Truncate, io::Write) {
Ok(f) => f,
Err(e) => panic!("file error: {}", e),
};
for line in lines.drain() {
file.write_str(line.as_slice());
}
}
fn main() {
let path = Path::new("test.txt");
let lines = read(&path);
write(&path, lines);
}
输出:
$ cat test.txt
a
a
b
a
a
b
a
b
$ ./dedup
$ cat test.txt
b
a
Rust 1.0
use std::io::{self,BufRead,Write};
use std::fs::File;
use std::collections::HashSet;
fn read(path: &str) -> HashSet<String> {
let file = File::open(path).unwrap();
let reader = io::BufReader::new(file);
reader.lines().map(|x| x.unwrap()).collect()
}
fn write(path: &str, lines: HashSet<String>) {
let mut file = File::create(path).unwrap();
for line in lines {
writeln!(file, "{}", line).unwrap();
}
}
fn main() {
let path = "test.txt";
let lines = read(path);
write(path, lines);
}