#include "dir.h"
#include <iostream>
#include <string>
CDir::CDir(Fat *fat)
{
_fat = fat;
_rootdir_start_sector = fat->get_sectors_before_fat() + fat->get_fat_nums() * fat->get_fat_sectornums();
_rootdir_sectors = fat->get_rootentrys_nums() * 32 / fat->get_sector_bytes();
_fat0_start_sector = fat->get_sectors_before_fat();
_fat1_start_sector = _fat0_start_sector + fat->get_fat_sectornums();
_other_start = _rootdir_start_sector+_rootdir_sectors;
}
void CDir::_show_dir(int from, int n)
{
unsigned char * buffer = new unsigned char[_fat->get_sector_bytes()];
for(int i=0; i<n; i++,from++){
if(!_fat->sectorRead(from,buffer)){
std::cout<<"读取第"<<from<<"块dir失败\n";
delete [] buffer;
return;
}
int dirs_persec = _fat->get_sector_bytes() / 32;
Dir32 * pDir;
//一个buffer中有16个目录项,挨个赋值给Dir结构,解析目录
unsigned char * tmp = buffer;
char filename[9];
char exname[4];
for(int j=0; j< dirs_persec; j++,tmp += 32){
pDir = (Dir32 *)tmp;
unsigned char first = (unsigned char)pDir->filename[0];
//卷标不显示
if(pDir->property.volume == 1)
continue;
if(first != 0xe5 && first != 0x0){
//文件名和扩展名都不是以'\0'结尾的字符串,需要转换
_char_to_string(pDir->filename,filename,8);
if(first == 0x05)
filename[0] = (char)0xe5;
_char_to_string(pDir->exname,exname,3);
std::cout<<filename;
if(pDir->property.dir ==1)
std::cout<<"\t<dir>";
else
std::cout<<"\t"<<exname;
//时间从1980年开始
std::cout<<"\t"<<pDir->date.year+1980<<"."<<pDir->date.month<<"."<<pDir->date.day;
std::cout<<"\t"<<pDir->time.hour<<":"<<pDir->time.minute<<":"<<pDir->time.second;
std::cout<<std::endl;
}
}
}
delete [] buffer;
}
void CDir::show_rootdir()
{
_show_dir(_rootdir_start_sector, _rootdir_sectors);
}
EntryPos CDir::_find_file(std::string name)
{
//跟前面的代码dup的太多了,不知道怎么才能复用
unsigned char *buffer = new unsigned char[_fat->get_sector_bytes()];
int from = _rootdir_start_sector;
int n = _rootdir_sectors;
EntryPos entrypos;
entrypos.sector = -1;
entrypos.offset = -1;
for(int i=0; i<n; i++,from++){
if(!_fat->sectorRead(from,buffer)){
std::cout<<"读取第"<<from<<"块dir失败\n";
delete [] buffer;
return entrypos;
}
int dirs_persec = _fat->get_sector_bytes() / 32;
Dir32 * pDir;
unsigned char * tmp = buffer;
char filename[9];
char exname[4];
for(int j=0; j< dirs_persec; j++,tmp += 32){
pDir = (Dir32 *)tmp;
_char_to_string(pDir->filename,filename,8);
_char_to_string(pDir->exname,exname,3);
std::string strname ="";
strname += filename;
strname +=".";
strname +=exname;
//不能区分大小写
if(strcmp(strlwr((char *)strname.c_str()),strlwr((char *)name.c_str())) == 0){
entrypos.sector = from;
entrypos.offset = j;
delete [] buffer;
return entrypos;
}
}
}
delete [] buffer;
return entrypos;
}
void CDir::_char_to_string(char *s,char *d,int n)
{
for(int k =0; k<n; k++){
if((unsigned char )s[k] == 0x20){
d[k]='\0';
return;
}
d[k]=s[k];
}
d[n] = '\0';
}
void CDir::change_name(std::string sname,std::string dname)
{
EntryPos entrpos = _find_file(sname);
if(entrpos.sector < 0 || entrpos.offset < 0){
std::cout<<"文件"<<sname<<"不存在\n";
return;
}
EntryPos entrpos2 = _find_file(dname);
if(entrpos2.sector > 0 && entrpos2.offset >= 0){
std::cout<<"文件"<<dname<<"已经存在\n";
return;
}
unsigned char *buffer = new unsigned char[12];
unsigned char *tmp = buffer;
int index = dname.find_first_of('.');
//文件名
int offset = entrpos.offset*32;
strcpy((char *)tmp,dname.substr(0,index).c_str());
strupr( (char*)tmp);
//扩展名
tmp += 8;
strcpy((char*)tmp,dname.substr(index+1,3).c_str());
strupr((char *)tmp);
//少于8字节的名字用0x20补齐
for(int i=index;i<8;i++)
buffer[i] = 0x20;
_fat->sectorWrite(entrpos.sector,buffer,offset,11);
delete [] buffer;
}
void CDir::del_file(std::string sname)
{
EntryPos entrypos = _find_file(sname);
if(entrypos.offset<0 || entrypos.sector <0){
std::cout<<"文件"<<sname<<"不存在\n";
return;
}
unsigned char * buffer = new unsigned char[_fat->get_sector_bytes()];
_fat->sectorRead(entrypos.sector,buffer);
//定位目录项
unsigned char * p = buffer;
p += entrypos.offset * 32;
Dir32 * pDir;
pDir = (Dir32 *)p;
pDir->filename[0]=(unsigned char)0xe5;
_del_fat12(pDir->start_cluster,_fat0_start_sector);
_del_fat12(pDir->start_cluster,_fat1_start_sector);
_fat->sectorWrite(entrypos.sector,(unsigned char *)pDir,entrypos.offset*32,32);
delete [] buffer;
}
void CDir::_del_fat12(int start_cluster,int fat_start_sector)
{
unsigned char *buffer = new unsigned char [_fat->get_sector_bytes()];
int cur_cluster = start_cluster;
while(1){
//0空闲,0xff7坏道,0x8ff--0xfff结束
if(cur_cluster == 0x0 || cur_cluster >0xff7 && cur_cluster<0xfff)
break;
Fat12_Return fatReturn = _find_fat12_cluster(cur_cluster,fat_start_sector);
Fat12_Entry *pfat12entry = &fatReturn.entry;
int n = fatReturn.n;
int offset = fatReturn.offset;
int sector = fatReturn.sector;
if(cur_cluster %2 == 0){
cur_cluster = pfat12entry->entry0;
pfat12entry->entry0 =0x0;
}
else{
cur_cluster = pfat12entry->entry1;
pfat12entry->entry1 = 0x0;
}
if(n<3){
_fat->sectorWrite(sector,(unsigned char*)pfat12entry,offset,n);
_fat->sectorWrite(sector+1,(unsigned char*)(pfat12entry + n),0,3-n);
}
else
_fat->sectorWrite(sector,(unsigned char*)pfat12entry,offset,3);
}
delete [] buffer;
return;
}
void CDir::copy_file(std::string sname,std::string dname)
{
EntryPos entrpos = _find_file(sname);
if(entrpos.sector < 0 || entrpos.offset < 0){
std::cout<<"文件"<<sname<<"不存在\n";
return;
}
EntryPos entrpos2 = _find_file(dname);
if(entrpos2.sector > 0 && entrpos2.offset >= 0){
std::cout<<"文件"<<dname<<"已经存在\n";
return;
}
int sCluster = _find_fat12_entry(entrpos);
EntryPos dEntrypos = _add_dir_entry(entrpos,dname);
int dCluster = _find_fat12_entry(dEntrypos);
_copy_file(sCluster,dCluster,_fat0_start_sector);
}
void CDir::_copy_file(int sCluster,int dCluster,int fat_start_sector)
{
int sCur_cluster = sCluster;
int dCur_cluster = dCluster;
while(1){
//0空闲,0xff7坏道,0x8ff--0xfff结束
if(sCur_cluster == 0x0 || sCur_cluster >=0xff7 && sCur_cluster<=0xfff)
return;
//fat中的第二项对应文件中的第0项
for(int i=0;i<_fat->get_sector_PerCluster();i++)
_fat->sectorCopy(_other_start-2 + sCluster+i, 0,_other_start-2 + dCur_cluster+i,0,_fat->get_sector_bytes());
Fat12_Return sFatReturn = _find_fat12_cluster(sCur_cluster,fat_start_sector);
if(sCur_cluster %2 == 0)
sCur_cluster = sFatReturn.entry.entry0;
else
sCur_cluster = sFatReturn.entry.entry1;
int new_dCluster = _find_bank_fat12_entry();
Fat12_Return dFatReturn = _find_fat12_cluster(dCur_cluster,fat_start_sector);
//建立链表
if(dCur_cluster %2 == 0)
dFatReturn.entry.entry0 = new_dCluster;
else
dFatReturn.entry.entry1 = new_dCluster;
dCur_cluster = new_dCluster;
if(dFatReturn.n<3){
_fat->sectorWrite(dFatReturn.sector,(unsigned char*)&dFatReturn.entry ,dFatReturn.offset,dFatReturn.n);
_fat->sectorWrite(dFatReturn.sector+1,(unsigned char*)(&dFatReturn.entry + dFatReturn.n),0,3-dFatReturn.n);
}
else
_fat->sectorWrite(dFatReturn.sector,(unsigned char*)&dFatReturn.entry,dFatReturn.offset,3);
}
}
Fat12_Return CDir::_find_fat12_cluster(int cur_cluster,int fat_start_sector)
{//定位fat12文件的文件项偏移未知真是麻烦,都格式化无数次软盘了
unsigned char * fat_entry = new unsigned char[sizeof(Fat12_Entry )];
unsigned char *buffer = new unsigned char [_fat->get_sector_bytes()];
int sector = _get_fat12_entry_sector(cur_cluster) + fat_start_sector;
//offset是偏移字节数
//求of
没有合适的资源?快使用搜索试试~ 我知道了~
FAT文件系统磁盘IO读取(vc实现)
共13个文件
h:4个
cpp:3个
plg:1个
4星 · 超过85%的资源 需积分: 10 79 下载量 5 浏览量
2009-05-17
11:11:23
上传
评论 1
收藏 566KB RAR 举报
温馨提示
通过针对FAT12文件系统软盘进行文件I/O读取,了解与掌握FAT12文件系统,开发环境为VC
资源推荐
资源详情
资源评论
收起资源包目录
os_project4.rar (13个子文件)
os_project4
fat.h 1020B
test.cpp 1KB
disk.h 451B
os_project4.plg 2KB
fat.cpp 5KB
dir.h 3KB
os_project4.dsw 545B
os_project4.ncb 97KB
os_project4.dsp 5KB
dir.cpp 12KB
root.h 970B
os_project4.opt 49KB
Debug
os_project4.bsc 2.1MB
共 13 条
- 1
waken_ma
- 粉丝: 3
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页