I have a directory where there are some script files, some binary files, and some subdirectories. I have tried to write a program which gets names of all files in directory, and excludes if they are directory or binary files. It then reads first line of each file, excludes if "bin" is not there. Then it splits first line by "/" character and gets last string. Hence for first line of "#! /bin/bash", it will get "bash". Then it adds these program names to a HashMap to keep a count and shows it at the end.
Hence, many steps are involved. My program is working, but I feel it can be much optimized as I am just learning Rust.
use std::fs::*;
use std::env;
use std::io::*;
use std::io::prelude::*;
use std::collections::HashMap;
use std::io::{BufReader,BufRead};
use content_inspector::{ContentType, inspect};
use std::path::PathBuf;
fn main() {
let paths = std::fs::read_dir(".").expect("Not able to read dir.");
let mut filecount = 0;
let mut binarycount =0;
let mut dircount =0;
let mut progdict = HashMap::new();
for path in paths{
println!("=========== PATH ===============");
let fname = path.unwrap().path();
println!("fname: {}", fname.display());
let pb = PathBuf::from(fname.clone());
let is_dir = pb.is_dir();
if is_dir {
println!("A directory found: {}", pb.display());
dircount += 1;
continue;
}
filecount += 1;
println!("Not directory; checking further...files checked: {}", filecount);
let mut MyBuf = BufReader::new(File::open(fname.clone()).expect("Unable to open file"));
let mut binary = false;
for ch in MyBuf.bytes(){
if ch.unwrap() > 127{
println!("BINARY FILE FOUND");
binary = true;
binarycount += 1;
break;
}
}
if binary {continue;}
println!("Not binary, getting first line.");
// else check first line:
let file = File::open(fname).expect("cannot open file");
let file = BufReader::new(file);
let mut progname: String ="".to_string();
for line in file.lines() {
let linestr = line.unwrap();
println!("FIRSTLINE: {}", linestr);
if !linestr.contains("bin"){
println!("Not script file....");
break
}
let parts = linestr.split("/").collect::<Vec<&str>>();
progname = parts[parts.len()-1].trim().to_string();
println!("Program name: {}", progname);
break; // we need to see first line only;
}
progdict.entry(progname).and_modify(|x| *x += 1 ).or_insert(1);
}// end for path in paths;
println!("Total files checked: {}; binary files found: {}; dirs found: {}", filecount, binarycount, dircount);
for (k,v) in progdict{
println!("{} :\t\t\t{}", k, v);
}
}//end main
How can above program be improved? Thanks for your insight.