从我看到的in the documentation开始,没有开箱即用的解决方案。
答案 0 :(得分:7)
use std::fs;
use std::path::{Path, PathBuf};
pub fn copy<U: AsRef<Path>, V: AsRef<Path>>(from: U, to: V) -> Result<(), std::io::Error> {
let mut stack = Vec::new();
stack.push(PathBuf::from(from.as_ref()));
let output_root = PathBuf::from(to.as_ref());
let input_root = PathBuf::from(from.as_ref()).components().count();
while let Some(working_path) = stack.pop() {
println!("process: {:?}", &working_path);
// Generate a relative path
let src: PathBuf = working_path.components().skip(input_root).collect();
// Create a destination if missing
let dest = if src.components().count() == 0 {
output_root.clone()
} else {
output_root.join(&src)
};
if fs::metadata(&dest).is_err() {
println!(" mkdir: {:?}", dest);
fs::create_dir_all(&dest)?;
}
for entry in fs::read_dir(working_path)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
stack.push(path);
} else {
match path.file_name() {
Some(filename) => {
let dest_path = dest.join(filename);
println!(" copy: {:?} -> {:?}", &path, &dest_path);
fs::copy(&path, &dest_path)?;
}
None => {
println!("failed: {:?}", path);
}
}
}
}
}
Ok(())
}
其他答案实际上并没有显示该如何做,只是说您可能如何做;这是一个具体的例子。
如其他答案所述,相关的API为fs::create_dir_all
,fs::copy
和fs::metadata
。
没有为此提供“所有功能”的标准库API。
答案 1 :(得分:4)
您可以使用我撰写的fs_extra crate。此包会扩展标准库std::fs
和std::io
模块。
它可以(除其他外):
答案 2 :(得分:3)
您可以使用std::io::fs::walk_dir
递归遍历目录结构,这会产生Result
中的迭代器,并且对于每个Path
,使用{{检查它是否是一个文件3}} PathExtensions
扩展特性提供的方法。如果是,则使用is_file()
实际复制文件。
答案 3 :(得分:0)
fs_extra
根本不适合我。它还具有令人困惑的选项,并且总体质量令人怀疑(例如,他们认为64000字节为64 kB)。
无论如何,可行的替代方法是copy_dir
,它包含一个执行此操作的函数,没有选项。它不会覆盖现有目录,但是您可以修改代码以使其非常容易。
答案 4 :(得分:0)
我找到的最简单的代码有效:
use std::{io, fs};
fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
fs::create_dir_all(&dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let ty = entry.file_type()?;
if ty.is_dir() {
copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?;
} else {
fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
}
}
Ok(())
}