我正在尝试创建一个简单的函数,该函数使用hyper将远程文件下载到本地文件路径。我还需要文件写入也要异步(就我而言,我正在使用$polaczenie = new mysqli($host, $db_user, $db_password, $db_name);
if ($polaczenie->connect_errno!=0)
{
echo "Error: ".$polaczenie->connect_errno;
}
else
{
$select = $polaczenie->query("INSERT INTO warszawa.typy_pojazdow (typ, nazwa) SELECT type, description from rfid.vehicle_types");
}
)。这是代码:
tokio_fs
但是,出现以下错误:
// Parts of the code were omitted, see the playground for full source code
pub fn download_file(
uri: Uri,
file_location: &Path,
) -> Box<Future<Item = (), Error = DownloadFileError>> {
let temp_dir_path = tempfile::tempdir().unwrap().into_path();
let file_name = match file_location.file_name() {
Some(file_name) => file_name,
None => return Box::new(futures::failed(DownloadFileError::IncorrectFilePath)),
};
let temp_filepath = temp_dir_path.join(&file_name);
let connector = HttpsConnector::new(2).unwrap();
let client: Client<_, Body> = Client::builder().build(connector);
let response_future = client
.get(uri)
.map_err(|err| DownloadFileError::GetRequest(err));
let create_file_future =
File::create(temp_filepath).map_err(|err| DownloadFileError::CreateFile(err));
Box::new(
response_future
.join(create_file_future)
.and_then(move |(res, file)| {
res.into_body()
.map_err(|e| DownloadFileError::GetRequest(e))
.for_each(move |chunk| {
io::write_all(file, chunk)
.map(|_| ())
.map_err(|_| DownloadFileError::FileWrite)
})
}),
)
}
从概念上讲,我理解错误的含义:由于error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
--> src/lib.rs:79:39
|
75 | .and_then(move |(res, file)| {
| ---- captured outer variable
...
79 | io::write_all(file, chunk)
| ^^^^ cannot move out of captured outer variable in an `FnMut` closure
通过可变引用捕获变量,因此无法移动捕获的变量。但是,由于我需要将流写入FnMut
Future返回的文件中,因此我在给定的示例中不了解如何解决此问题。
Join
特性中的write_all
方法在这里可以工作,因为它将文件作为可变引用,但是问题在于它是在同一线程上进行写操作。
答案 0 :(得分:3)
您不想使用for_each
。 io::write_all
消耗目标和缓冲区,以换取将来将在完成时返回目标和缓冲区的将来。您可以将其与Stream::fold
结合使用以重新使用文件:
.fold(file, |file, chunk| {
io::write_all(file, chunk)
.map(|(f, _c)| f)
.map_err(|_| DownloadFileError::FileWrite)
})
.map(drop)
另请参阅: