

※Rust勉強中のため、プログラムが最適かどうかは不明です・・・。特にエラー処理の作法については試行錯誤中です。より良い書き方があれば、そちらを参考にしてください。
CODE
use std::fs::File;
use std::io::{Write};
use std::io::{BufRead, BufReader};
#[tokio::main]
async fn main() -> Result<(), Box> {
let max_download_num=10;
let file_name="download.csv";
let sep="\t";
let mut data_from;
let mut file_to;
let mut no:i32=0;
let mut li:i32=0;
for result in BufReader::new(File::open(file_name)?).lines() {
if li>=max_download_num {
break;
}
li=li+1;
let line:String = result?;
let v: Vec<&str> = line.split(sep).collect();
if v.len()<2 {
println!("Line No.{} skipped.", li);
continue;
}
data_from=v[0];
file_to=v[1];
let resp=reqwest::get(data_from).await;
if let Err(e) = resp {
println!("Line No.{} Access Error : URL={} ",li,data_from);
if e.is_redirect() {
if let Some(final_stop) = e.url() {
println!("redirect loop at {}", final_stop);
}
}
else if e.is_timeout() {
println!("time out");
}
else if e.is_status() {
let code=e.status();
println!("status code = {}",code.unwrap());
}
else{
println!("Unknown Error");
}
continue;
}
let _data=resp.unwrap().bytes().await;
if let Err(_) = _data {
continue;
}
let _buf = _data.unwrap();
no=no+1;
println!("{} Received... {}",no,data_from);
let fresp = File::create(file_to);
if let Err(_) = fresp {
println!("Line No.{} File create Error(No.{} was received but canceled.)...{}",li,no,file_to);
no = no-1;
continue;
}
let mut file = fresp.unwrap();
file.write_all(&_buf)?;
file.flush()?;
println!("{} Written ... {}",no,file_to);
}
println!("Done. {} line(s) processed, {} file(s) downloaded.",li,no);
Ok(())
}
download.csvの例は以下の通り。
https://example.com/test.pdf test.pdf https://example2.net/picture.jpg picture.jpg http://example3.org/sample.png sample.png
Cargo.toml には、以下を追加。
[dependencies]
reqwest = { version = "0.10" }
tokio = { version = "0.2", features = ["full"] }