#![allow(unused)]
use std::io::{SeekFrom,BufReader, BufWriter, Read, Write,Seek};
use std::collections::HashMap;
use std::fs::{File,metadata,OpenOptions};
pub fn make(files_block: &HashMap<&str, u64>) -> std::io::Result<()> {
let mut files_size=0_u64;
match all_file_exist(files_block){
Ok(size)=>{
files_size=size;
},
Err(v)=>{
for msg in v{
println!("{}文件不存在",msg);
}
panic!("上述文件不存在,无法编译");
}
}
println!("boot、loader、kernel文件总大小{}",files_size);
let target_file_path="disk.img";
let target_file = File::create(target_file_path)?;
target_file.set_len(files_size/512+1)?;
for (file,block) in files_block{
println!("文件:{},写入起始扇区号:{},大小:{}字节",file,block,metadata(file).unwrap().len());
write_offset(file,target_file_path,block*512);
}
let disk_meta=metadata(target_file_path)?;
println!("镜像文件总大小:{}字节",disk_meta.len());
Ok(())
}
fn all_file_exist<'a>(file_block: &'a HashMap<&'a str, u64>)->Result<u64, Vec<&'a str>>{
let mut size=0_u64;
let mut v:Vec<&str>=Vec::new();
for (file_path,_) in file_block {
match metadata(file_path){
Ok(meta)=>{
size+=meta.len();
},
Err(_)=>{
v.push(file_path);
}
}
}
if v.len()==0{
Ok(size)
}else{
Err(v)
}
}
fn write_offset(source_path:&str,target_path:&str,offset:u64)->std::io::Result<()>{
let mut source_file = BufReader::new(File::open(source_path)?);
let mut target_file = OpenOptions::new()
.write(true)
.create(true)
.open(target_path)?;
target_file.seek(SeekFrom::Start(offset))?;
let mut buffer = [0; 1024]; loop {
let bytes_read = source_file.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
target_file.write(&buffer[0..bytes_read])?;
}
target_file.flush()?;
drop(target_file);
Ok(())
}