Skip to content
This repository has been archived by the owner on Dec 19, 2022. It is now read-only.

Commit

Permalink
Export to csv files
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexandre Stein committed Feb 13, 2021
1 parent 6abcfe2 commit 69d6b78
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 11 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ Cargo.lock
**/*.rs.bk

# End of https://www.gitignore.io/api/rust

fs-scan_output.csv
85 changes: 85 additions & 0 deletions src/csv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use std::fs::OpenOptions;
use std::io::BufRead;
use std::io::BufReader;
use std::io::Write;

use super::objects;

static OUTPUT_FILE: &'static str = "fs-scan_output.csv";
static FILE_FIRST_LINE: &'static str = "Path,Files,Directories,4K,4K_16K,16K_64K,64K_128K,128K_256K,256K_512K,512K_1M,1M_10M,10M_100M,100M_1G,1G";

pub fn save(res: &objects::Result) {
match check_file() {
Err(s) => {
println!("ERROR on check: {}", s);
return;
}
Ok(s) => println!("SUCCESS on check: {}", s),
}

let mut file = OpenOptions::new()
.write(true)
.append(true)
.open(&OUTPUT_FILE)
.unwrap();

if let Err(_) = writeln!(file, "{}", res.result_to_string()) {
return;
}
}

fn check_file() -> Result<String, String> {
// Open the file
let mut file = match OpenOptions::new()
.read(true)
.write(true)
.open(&OUTPUT_FILE)
{
Err(_) => {
// File not opened
// Try to create it
let file = match OpenOptions::new()
.write(true)
.read(true)
.append(true)
.create(true)
.open(&OUTPUT_FILE)
{
Err(_) => return Err("can't open/create new file".to_string()),
Ok(file) => file,
};
file
}
Ok(file) => file,
};

match file.metadata() {
Ok(m) => {
if m.len() == 0 {
if let Err(_) = writeln!(&mut file, "{}", &String::from(FILE_FIRST_LINE)) {
return Err("can't write first line".to_string());
}
return Ok("new file created and first line added successfully".to_string());
}
}
Err(_) => return Err("Can't get meta".to_string()),
}

// Check the first line is valid
//
// Read the content
let file_content = BufReader::new(&file);
for line in file_content.lines() {
// let l = line.unwrap();
let l = match line {
Ok(l) => l,
Err(e) => return Err(format!("can't read line: {}", e)),
};
if l == FILE_FIRST_LINE {
break;
}
return Err(format!("Not the same line: content {}", l));
}

Ok("first line valid, can add the new report".to_string())
}
22 changes: 13 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
mod csv;
mod objects;

use std::env;
use std::fs;
use std::path::PathBuf;
use std::sync::mpsc::{channel, Sender};
use std::thread;
use std::time;
use std::{fs, io};

use indicatif::{HumanDuration, ProgressBar, ProgressStyle};
use num_cpus;



fn main() -> io::Result<()> {
fn main() {
let mut path = PathBuf::from(".");
let args: Vec<_> = env::args().collect();
if args.len() > 1 {
println!("The path is {}", args[1]);
path = PathBuf::from(&args[1]);
};

let mut res = objects::build_result();
let mut res;
match &path.to_str() {
Some(path_as_string) => res = objects::build_result(path_as_string),
None => res = objects::build_result(""),
}

// build channel
let (sender, receiver) = channel();
Expand All @@ -43,7 +46,9 @@ fn main() -> io::Result<()> {
let starting_point = time::Instant::now();

let display_refresh_time = time::Duration::from_millis(250);
let mut last_message = time::Instant::now().checked_sub(display_refresh_time.clone()).expect("to remove some time");
let mut last_message = time::Instant::now()
.checked_sub(display_refresh_time.clone())
.expect("to remove some time");

// Handle responses
for received in receiver {
Expand Down Expand Up @@ -89,7 +94,6 @@ fn main() -> io::Result<()> {
}
match dir_queue.pop() {
Some(dir) => {

// // Add latency to debug the display
// thread::sleep(time::Duration::from_millis(5));

Expand All @@ -108,6 +112,8 @@ fn main() -> io::Result<()> {
}
bar.finish();

csv::save(&res);

println!("Scan took {}", HumanDuration(starting_point.elapsed()));
println!("Files -> {}", nice_number(res.files));
println!("Directories -> {}", nice_number(res.directories));
Expand Down Expand Up @@ -157,8 +163,6 @@ fn main() -> io::Result<()> {
nice_number(res.between_100_m_1_g)
);
println!("More than 1GB -> {}", nice_number(res.more_than_1_g));

Ok(())
}

fn nice_number(input: usize) -> String {
Expand Down
30 changes: 28 additions & 2 deletions src/objects.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::path::PathBuf;

pub struct Result {
pub path: String,
pub files: usize,
pub directories: usize,
pub less_than_4_k: usize,
Expand All @@ -17,8 +18,10 @@ pub struct Result {
pub between_100_m_1_g: usize,
pub more_than_1_g: usize,
}
pub fn build_result() -> Result {
pub fn build_result(path: &str) -> Result {
Result {
path: String::from(path),

files: 0,
directories: 0,

Expand All @@ -38,6 +41,29 @@ pub fn build_result() -> Result {
}
}

impl Result {
pub fn result_to_string(&self) -> String {
format!(
"{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}",
&self.path,
&self.files,
&self.directories,
&self.less_than_4_k,
&self.between_4_k_8_k,
&self.between_8_k_16_k,
&self.between_16_k_32_k,
&self.between_32_k_64_k,
&self.between_64_k_128_k,
&self.between_128_k_256_k,
&self.between_256_k_512_k,
&self.between_512_k_1_m,
&self.between_1_m_10_m,
&self.between_10_m_100_m,
&self.between_100_m_1_g,
&self.more_than_1_g,
)
}
}

pub enum ResponseType {
File,
Expand Down Expand Up @@ -69,4 +95,4 @@ pub fn build_file_chan(size: u64) -> ChanResponse {
path: PathBuf::new(),
len: size,
}
}
}

0 comments on commit 69d6b78

Please sign in to comment.