编写的工具是VS2017
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string>
#include <io.h>
#include <malloc.h>
#include <direct.h>
#include <time.h>
//#include <WinSock2.h>
//#include <iostream>
//#pragma comment(lib, "Ws2_32.lib")
//#include <vector>
//#include <sys/stat.h>
typedef long long int64;
typedef long long int64;
int txtInit(char *textname) {
FILE *fp = fopen(textname, "w");
if (fp == NULL) {
return 0;
}
else {
fclose(fp);
return 1;
}
}
int txtPuts(char *textname, char *word) {
FILE *fp = fopen(textname, "a+");
if (fp == NULL) {
return 0;
}
else {
fputs(word, fp);
fclose(fp);
return 1;
}
}
int64 txtLen(char *textname) {
int64 len = 0;
FILE *fp = fopen(textname, "r");
if (fp == NULL) {
return -1;
}
else {
len = 0;
while (1) {
int c = fgetc(fp);
if (c == -1)break;
len++;
}
fclose(fp);
return len;
}
}
int txtGets(char *textname, char *dest) {
FILE *fp = fopen(textname, "r");
if (fp == NULL) {
return 0;
}
else {
int64 i = 0;
while (1) {
int c = fgetc(fp);
if (c == -1)break;
dest[i] = c;
i++;
}
fclose(fp);
return 1;
}
}
int logPuts(const char *log) {
time_t t;
time(&t);
struct tm *pt = localtime(&t);//静态指针,不需要释放(但也不能在多线程环境使用(我猜或许要加锁))
char buf[1024];
sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d %s\n", pt->tm_year + 1900, pt->tm_mon + 1, pt->tm_mday, pt->tm_hour, pt->tm_min, pt->tm_sec,
log);
txtPuts((char*)"logs.txt", buf);
return 0;
}
struct _Mem_Disk {
unsigned char *wr;
unsigned char Mem[1 * 1024 * 1024];
};
struct _Mem_Disk md;
int fputs_img_disk(FILE*fp, int64 offset, void *src_, int64 len) {
char *src = (char*)src_;
int64 thenoffset;
//_fseeki64(fp, 0, 0);
//int64 start = _ftelli64(fp);//得到偏移距离
if (len <= 0)return -1;
while (1) {
while (_fseeki64(fp, offset, 0) != 0);
thenoffset = _ftelli64(fp);
if (thenoffset == offset)break;
}
int64 i = 0;
while (i<len) {
int c = (int)src[i];
fputc(c, fp);
i++;
}
return 0;
}
int fgets_img_disk(FILE*fp, int64 offset, void *des_, int64 len) {
char *des = (char*)des_;
int64 thenoffset;
//_fseeki64(fp, 0, 0);
//int64 start = _ftelli64(fp);//得到偏移距离
if (len <= 0)return -1;
while (1) {
while (_fseeki64(fp, offset, 0) != 0);
thenoffset = _ftelli64(fp);
if (thenoffset == offset)break;
}
int64 i = 0;
while (i<len) {
int c = fgetc(fp);
if (c == -1)return -1;//没能完整读取完整个长度,返回-1报错
des[i] = c;
i++;
}
return 0;
}
//考虑用内存代替部分文件空间,好处就是,在对配置信息重复读写的时候,可以加快速度(还在构思怎么实现)
int mfseek(int64 offset,char type) {
if (type == 0) {
md.wr = md.Mem + offset;
return 0;
}
else {
return -1;
}
}
int64 mftell() {
return (int64)(md.wr - md.Mem);
}
int mfputc(int c) {
*md.wr = c;
md.wr++;
return 0;
}
unsigned int mfgetc() {
unsigned int c = *md.wr;
md.wr++;
return c;
}
int fputs_img_mem(FILE*fp, int64 offset, void *src_,int64 len) {
char *src = (char*)src_;
int64 thenoffset;
if (len <= 0)return -1;
while (1) {
while (mfseek( offset, 0) != 0);
thenoffset = mftell();
if (thenoffset == offset)break;
}
int64 i = 0;
while (i<len) {
int c = (int)src[i];
mfputc(c);
i++;
}
while (1) {
while (mfseek( offset, 0) != 0);
thenoffset = mftell();
if (thenoffset == offset)break;
}
i = 0;
while (i<len) {
int c = src[i];
int tc = mfgetc();
if (c != tc) {
return -1;
}
i++;
}
return 0;
}
int fgets_img_mem(FILE*fp, int64 offset, void *des_, int64 len) {
char *des = (char*)des_;
int64 thenoffset;
if (len <= 0)return -1;
while (1) {
while (mfseek( offset, 0) != 0);
thenoffset = mftell();
if (thenoffset == offset)break;
}
int64 i = 0;
while (i<len) {
int c = mfgetc();
//printf("55555555555555555 = %d\n", c);
if (c == -1)return -1;//没能完整读取完整个长度,返回-1报错
des[i] = c;
i++;
}
while (1) {
while (mfseek(offset, 0) != 0);
thenoffset = mftell();
if (thenoffset == offset)break;
}
i = 0;
while (i<len) {
int c = des[i];
int tc = mfgetc();
if (c != tc) {
return -1;
}
i++;
}
return 0;
}
int fputs_img(FILE*fp, int64 offset, void *src_, int64 len) {
return fputs_img_disk(fp,offset,src_,len);
}
int fgets_img(FILE*fp, int64 offset, void *des_, int64 len) {
return fgets_img_disk(fp, offset, des_, len);
}
//计算文件长度
int64 fileLen(FILE *fp1) {
FILE *fp2 = fp1;
int64 i, start, end;
sta:
while (_fseeki64(fp2, 0, 0) != 0);//返回开头(返回0表示移动成功)
start = _ftelli64(fp2);
if (start >= 0) {}
else {
goto sta;
}
//printf("start = %d\n",start);
while (_fseeki64(fp2, 0, 2) != 0);
end = _ftelli64(fp2);
if (end >= 0) {}
else {
goto sta;
}
//printf("end = %d\n", end);
i = end - start;
//printf("i = %d\n", i);
while (_fseeki64(fp2, 0, 0) != 0);//返回开头
return i;
}
//创建一块空白区域(置0)
char fcreate_null_use_buf[4096] = {0};
int fcreate_null(FILE*fp, int64 offset, int64 len) {
char *buf= fcreate_null_use_buf;
int64 slen = len;
int64 soffset = offset;
int64 i = 0;
int tlen;
while (1) {
if (slen <= 0)break;
if (slen <= 4096) {
tlen = slen;
slen -= slen;
}
else {
tlen = 4096;
slen -= 4096;
}
fputs_img(fp, soffset, buf, tlen);
soffset += tlen;
}
return 0;
}
//以c字符初始化一块区域
int fsets_img(FILE*fp, int64 offset,int c, int64 len) {
char buf[4096];
memset(buf, c, 4096);
int64 slen = len;
int64 soffset = offset;
int64 i = 0;
int tlen;
while (1) {
if (slen <= 0)break;
if (slen <= 4096) {
tlen = slen;
slen -= slen;
}
else {
tlen = 4096;
slen -= 4096;
}
fputs_img(fp, soffset, buf, tlen);
soffset += tlen;
}
return 0;
}
#pragma pack(1)
struct _MYIMG_TYPE1 {
int64 imglen1;//当前镜像真实大小(物理磁盘上占据大小)
int64 imglen2;//当前镜像虚拟大小
int64 headlen;//头部长度,1024配置区和256M超级块区
int64 datalen;//数据区域长度(每一个数据块附带4个iNode)
int64 freeinodesize;
int64 freeoffset;//空闲区域起始位置
int64 freeoffsetend;//指向空闲区域末尾位置,便于追加空闲iNode
int64 rootoffset;//根目录起始位置
int64 rootinodesize;
int64 rootdirinodesize;
int64 rootfileinodesize;
};
struct _MYIMG_TYPE2 {
char type1;//类型标志1,1B
char type2;//标志2,备用,1B
int64 file_start;//文件起始位置,8B
int64 block_size;//8B
int64 block_num;//8B
int64 file_len;//文件长度,8B
int64 name_len;//名字长度,8B
int64 up_type2;//8B
int64 down_type2;//8B
int64 pr_type2;//8B
int64 ne_type2;//8B
char null[54];
};
#pragma pack()
//仅负责,新增数据区域的数据块
int64 AddDataBlock(FILE *fp, struct _MYIMG_TYPE1 *t1) {
int64 addlen = 4096*1024;//新增大概4M的数据区域
//如果即将新增的数据块加上已有的数据块,超出了预设大小限制,则返回-1报错
if (t1->imglen2 <= (addlen + t1->headlen + t1->datalen)) {
//printf("t1->imglen2 = %d\n", t1->imglen2);
return -1;
}
fcreate_null(fp, t1->headlen+t1->datalen, addlen);//偏移位置为,头部部分+已有数据部分
t1->datalen += addlen;//增加已有数据区域长度(注意,这里只是在内存里做了修改,还需要存入磁盘才能真正完成修改)
//还需要做一步操作,初始化块区的iNode块,将它们加入空闲表
return addlen;
}
//添加新的空闲块区,并负责把这些块区加入空闲iNode表
int64 AddFreeBlock(FILE *fp, struct _MYIMG_TYPE1 *t1) {
char type2buf[128];
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
int64 addlen= AddDataBlock(fp, t1);
//printf("addlen = %d\n", addlen);
if (addlen <= 0)return -1;
int64 offset = t1->datalen + t1->headlen - addlen;
if (t1->freeinodesize == 0) {
//当表为空时,freeoffset偏移地址需要重新设置,指向首个位置
t1->freeoffset = offset;
memset(type2buf, 0, 128);
}
else {
//当iNode数量不为0的时候,即存在新的空闲块区时
fgets_img(fp, t1->freeoffsetend, type2buf, sizeof(struct _MYIMG_TYPE2));
t2->ne_type2 = offset;
fputs_img(fp, t1->freeoffsetend, type2buf, sizeof(struct _MYIMG_TYPE2));
}
int i = 0;
while (i<1024) {
if (i == 0)
{
t2->pr_type2 = t1->freeoffsetend;//上一索引,可能是0,也可能是一个有效索引
t2->ne_type2 = offset + i * 4096 + 4096;
}
else if (i == 1023) {
t2->pr_type2 = offset + i * 4096 - 4096;
t2->ne_type2 = 0;
t1->freeoffsetend = offset + i * 4096;//配置信息的空闲iNode末尾偏移地址,需要指向这段新创建数据区域的末尾
}
else {
t2->pr_type2 = offset + i * 4096 - 4096;//(offset + i * 4096)是其本身的偏移地址
t2->ne_type2 = offset + i * 4096 + 4096;
}
fputs_img(fp, offset + i * 4096,type2buf,sizeof(struct _MYIMG_TYPE2));//信息写入文件
t1->freeinodesize++;//增加一个新的索引数量
i++;
}
return offset;//返回这段空闲块区的偏移地址,其实没什么用
}
//计算这个长度需要多少数据块
int64 NeedSuperBlock(int64 alllen) {
if (alllen < 0) {
return -1;//小于零是错误的
}
else if(alllen == 0) {
return 1;//当数据长度为0时,它需要一个数据块(不需要计算了)
}
else {
int64 r1 = alllen % 3584;
if (r1 == 0) {
int64 r2 = alllen / 3584;
return r2;
}
else {
int64 r2 = (alllen-r1) / 3584;
r2 += 1;//有余数则加1
return r2;
}
}
}
//尝试获取iNode,不成功返回-1
int64 GetiNode(FILE *fp) {
char buf[1024];
//memset(buf, 0, 1024);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[128];
//memset(type2buf, 0, 128);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));//读取配置信息
if (t1->freeinodesize == 0) {
return -1;//没有空闲iNode块,返回失败
}
fgets_img(fp, t1->freeoffset, type2buf, sizeof(struct _MYIMG_TYPE2));//读取iNode
int64 getoffset = t1->freeoffset;//得到的新iNode偏移地址
t1->freeoffset = t2->ne_type2;//配置信息的偏移地址指向下一个
t1->freeinodesize--;//空闲数量减1
fputs_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));//重新将配置信息写入
return getoffset;//返回iNode偏移地址
}
//分割路径
char *SubDirName(char*des, char *dir) {
int i = 0;
while (1) {
if (*dir == '\0') {
*des = '\0';
return NULL;
}
if (*dir == '\\') {
*des = '\0';
dir += 1;
return dir;
}
*des = *dir;
dir++;
des++;
}
}
//移动索引
#define UP_OFF 0x00
#define DOWN_OFF 0x01
#define PR_OFF 0x02
#define NE_OFF 0x03
#define CreateDir 0x01
#define CreateFile 0x02
int64 moveoffset(FILE *fp,int64 offset,char type) {
char type2buf[128];
//memset(type2buf, 0, 128);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
fgets_img(fp, offset, type2buf, sizeof(struct _MYIMG_TYPE2));
if (type == UP_OFF) {
return t2->up_type2;
}
else if (type == DOWN_OFF) {
return t2->down_type2;
}
else if (type == PR_OFF) {
return t2->pr_type2;
}
else if (type == NE_OFF) {
return t2->ne_type2;
}
}
//对上面移动索引的补充,往一个方向,移动索引,直到获取最后一个
int64 moveoffset_toend(FILE *fp, int64 offset, char type) {
int64 oldoffset = 0;
if (offset == 0)return -1;
while (1) {
oldoffset = offset;
offset = moveoffset(fp, oldoffset, type);
if (offset == 0)break;
}
return oldoffset;
}
//判断路径是否存在(不存在返回-1,存在返回文件或文件夹的偏移地址)
int64 HaveDir(FILE *fp,char *dir) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
int64 diroffset = t1->rootoffset;//根目录索引起点
//if (diroffset == 0)return -1;//根目录下为空,返回报错
char *p1 = dir;
char name[1024];
int i = 0;
int find = 0;
while (1) {
p1 = SubDirName(name, p1);
//printf("HaveDir() name = %s\n",name);
if (diroffset <= 0) {
return -1;
}
fgets_img(fp, diroffset, type2buf, 512);
if (t2->type1 != CreateDir) {
return -1;
}
diroffset = moveoffset(fp,diroffset,DOWN_OFF);
//printf("HaveDir() diroffset = %d\n", diroffset);
while (1) {
if (diroffset == 0) {
find = 0;//同级目录检查完毕,没有匹配文件名
break;
}
fgets_img(fp, diroffset, type2buf, 512);
//printf("HaveDir() type2buf+128 = %s\n", type2buf+128);
if (strcmp(type2buf + 128, name) == 0) {
find = 1;//同级目录找到目标
break;
}
diroffset = moveoffset(fp, diroffset, NE_OFF);
}
if (p1 == NULL)
{
if (find == 1) { return diroffset; }
else {
return -1;//到底了,但是没找到,报错吧
}
}
else {
if (find == 0) {
return -1;//同级目录没有匹配文件名,报错
}
else {
//没到底,但是找到匹配的,那就继续循环
}
}
i++;
}
}
//对上面同类函数的功能强化版,返回更多的信息,但是使用会麻烦一些
struct _HaveDirRet {
char dir[512];
char name[256][512];//将路径分成几段,分别存入256个键值
int64 offset[256];//记录找到匹配的文件夹/文件偏移位置
int64 ret;//返回报错信息,如果找到匹配文件或文件夹,返回匹配文件的偏移地址
int success_num;//返回最后匹配正确的路径键值(也是offset键值)
int namesize;//总共的路径段数
};
int64 HaveDirRet(FILE *fp, struct _HaveDirRet *hdr, char *dir) {
char buf[1024];
memset(buf, 0, 1024);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[512];
memset(type2buf, 0, 512);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
int64 diroffset = t1->rootoffset;//根目录索引起点
hdr->success_num = -1;//-1表示,根目录上就没有找到
char *p1 = dir;
int i = 0;
while (1) {
if (i == 256) {
hdr->ret = -1; return -1;//超出了256级目录的限制
}
p1 = SubDirName(hdr->name[i], p1);
i++;
if (p1 == NULL) {
break;
}
}
hdr->namesize = i;
p1 = dir;
i = 0;
int find = 0;
while (1) {
//printf("HaveDir() name = %s\n",name);
if (diroffset <= 0) {
hdr->ret = -1;
return -1;
}
fgets_img(fp, diroffset, type2buf, 512);
if (t2->type1 != CreateDir) {
hdr->ret = -1;
return -1;
}
diroffset = moveoffset(fp, diroffset, DOWN_OFF);
//printf("HaveDir() diroffset = %d\n", diroffset);
while (1) {
if (diroffset == 0) {
find = 0;//同级目录检查完毕,没有匹配文件名
break;
}
fgets_img(fp, diroffset, type2buf, 512);
//printf("HaveDir() type2buf+128 = %s\n", type2buf+128);
if (strcmp(type2buf + 128, hdr->name[i]) == 0) {
find = 1;//同级目录找到目标
hdr->success_num = i;//最后找的的那个文件名数组键值
hdr->offset[i] = diroffset;
break;
}
diroffset = moveoffset(fp, diroffset, NE_OFF);
}
i++;
if (i == hdr->namesize)
{
if (find == 1) { hdr->ret = diroffset; return diroffset; }
else {
hdr->ret = -1;
return -1;//到底了,但是没找到,报错吧
}
}
else {
if (find == 0) {
hdr->ret = -1;
return -1;//同级目录没有匹配文件名,报错
}
else {
//没到底,但是找到匹配的,那就继续循环
}
}
}
}
//建立第二个类似HaveDir的功能
//为程序提供获取iNode的保障
int64 GetiNodeBiuld(FILE *fp) {
int64 newinodeoffset = GetiNode(fp);//先尝试获取iNode
char buf[1024];
//memset(buf, 0, 1024);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));//从fp的0偏移位置获取sizeof(struct _MYIMG_TYPE1)个字符的数据到buf
if (newinodeoffset <= 0) {
int64 NewFreeOffset = AddFreeBlock(fp, t1);//创建新的块区
//printf("GetiNodeBiuld() NewFreeOffset = %d\n", NewFreeOffset);
if (NewFreeOffset <= 0)return -1;
fputs_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));//配置信息重新输入到文件
newinodeoffset = GetiNode(fp);//这一次,必然能获取到1个iNode块,因为刚刚创建新1024个4096字节的块,返回值不为-1
}
return newinodeoffset;//返回新块区的偏移地址
}
//对增加路径查找速度的想法
//首先,文件保存时,文件应按首字符的顺序排列,即0-255类似字典一样有索引
//查找某个路径是否存在,先判断首字符对应0-255的哪个数字,通过三个偏移地址指向
//三个偏移地址,一个指向0字符,一个指向128字符,一个指向255
//如,首字符为12,12距离0更近,就从0开始查找
//如,首字符为80,距离128更近,就从128开始查起
//还可以继续增加偏移地址的密度
//创建文件或文件夹(自动生成不存在的上层文件夹)
int64 CreateDir2(FILE *fp, char *dir,char type) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
char type2buf1[2048];
memset(type2buf1, 0, 2048);
struct _MYIMG_TYPE2 *t21 = (struct _MYIMG_TYPE2 *)type2buf1;
char type2buf2[2048];
memset(type2buf2, 0, 2048);
struct _MYIMG_TYPE2 *t22 = (struct _MYIMG_TYPE2 *)type2buf2;//保存当前新索引的各项信息
char name[1024],_dir[1024],*p1,*p2;
//memset(name, 0, 1204);
//memset(_dir, 0, 1204);
int64 offset,oldoffset;//一个保存最新获得的新偏移地址,一个保存上层文件夹的偏移地址
p1 = _dir;
p2 = dir;
int i = 0;
offset = -1;
int havedir = 1;
while (1) {
memset(type2buf2, 0, 2048);//初始化
p2 = SubDirName(p1, p2);
int64 ret;
if (havedir == 1) {
ret = HaveDir(fp, _dir);//从根目录开始,一层层尝试获取路径
}else{
ret = -1;
}
//返回-1,路径不存在
if (ret == -1) {
havedir = 0;//当上层目录不存在时,参数设为0,下次循环不再检查路径是否存在(目录是倒置的树状结构,根部不存在,下面也必然不
存在,就没有再判断路径是否存在的必要)
offset = GetiNodeBiuld(fp);//路径不存在,则需要新建路径节点
//i等于0,根目录下,上级节点需手动赋值
if (i == 0) {
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
oldoffset = t1->rootoffset;
}
//printf("-oldoffset = %d\n", oldoffset);
fgets_img(fp, oldoffset, type2buf, sizeof(struct _MYIMG_TYPE2));//偏移地址是上级节点
//printf("offset = %d\n", offset);
if (t2->down_type2 == 0) {
t2->down_type2 = offset;
}
else {
t22->ne_type2 = t2->down_type2;
fgets_img(fp, t2->down_type2, type2buf1, sizeof(struct _MYIMG_TYPE2));//偏移地址为,下级被替换节点
t21->pr_type2 = offset;
fputs_img(fp, t2->down_type2, type2buf1, sizeof(struct _MYIMG_TYPE2));
t2->down_type2 = offset;
}
fputs_img(fp, oldoffset, type2buf, sizeof(struct _MYIMG_TYPE2));
t22->up_type2 = oldoffset;
oldoffset = offset;//备下一次循环使用
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
if (p2 == NULL) {
if (type == CreateDir) {
t1->rootdirinodesize++;
t22->type1 = CreateDir;//设置索引类型(文件还是文件夹)
}
else if(type == CreateFile){
t1->rootfileinodesize++;
t22->type1 = CreateFile;
}
}
else {
t1->rootdirinodesize++;//还没到最底层目录,必然是文件夹
t22->type1 = CreateDir;
}
t22->block_size = 1;//占据数据块数量
t22->block_num = 1;
int64 namelen = strlen(p1);
t22->name_len = namelen;//设置文件名长度
memcpy(type2buf2 + 128, p1, namelen);//复制文件名
fputs_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));//写入配置信息
fputs_img(fp, offset, type2buf2, 512);//写入新索引信息
}
else {
oldoffset = ret;//找到可用路径
}
if (p2 == NULL) {
//p1 -= 1;//之前只创建一级目录时,出现内存读取错误,原因是这里的-=1,超出了数组边界
//*p1 = '\0';
break;
}
else {
p1+=strlen(p1);
*p1 = '\\';
p1 += 1;
}
i++;
}
//printf("%s\n",_dir);
return offset;
}
int64 CreateDir3(FILE *fp, struct _HaveDirRet *hdr, char *dir, char type) {
char buf[1024];
memset(buf, 0, 1024);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[128];//尽可能减少内存开销
memset(type2buf, 0, 128);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
char type2buf1[128];
memset(type2buf1, 0, 128);
struct _MYIMG_TYPE2 *t21 = (struct _MYIMG_TYPE2 *)type2buf1;
char type2buf2[512];
memset(type2buf2, 0, 512);
struct _MYIMG_TYPE2 *t22 = (struct _MYIMG_TYPE2 *)type2buf2;//保存当前新索引的各项信息
int64 offset, oldoffset;//一个保存最新获得的新偏移地址,一个保存上层文件夹的偏移地址
int i;
if (hdr->success_num <= -1) {
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
oldoffset = t1->rootoffset;//在根目录上也没有找到匹配文件名,上级节点初始化设为根目录
i = 0;//当前待生成的是根目录下的文件夹或文件
}
else {
oldoffset = hdr->offset[hdr->success_num];//找到部分匹配文件夹,上级节点初始化为最后匹配到的文件夹
i = hdr->success_num + 1;//当前待生成的是下级文件夹或文件
}
//继承HaveDirRet结果的文件或文件夹创建,不需要考虑路径是否已存在,因为HaveDirRet已经把这些都检测过
while (1) {
offset = GetiNodeBiuld(fp);
fgets_img(fp, oldoffset, type2buf, sizeof(struct _MYIMG_TYPE2));//偏移地址是上级节点
memset(type2buf2, 0, 512);
if (t2->down_type2 == 0) {
t2->down_type2 = offset;
}
else {
t22->ne_type2 = t2->down_type2;
fgets_img(fp, t2->down_type2, type2buf1, sizeof(struct _MYIMG_TYPE2));//偏移地址为,下级被替换节点
t21->pr_type2 = offset;
fputs_img(fp, t2->down_type2, type2buf1, sizeof(struct _MYIMG_TYPE2));
t2->down_type2 = offset;
}
fputs_img(fp, oldoffset, type2buf, sizeof(struct _MYIMG_TYPE2));
t22->up_type2 = oldoffset;
oldoffset = offset;//备下一次循环使用
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
if (i == (hdr->namesize-1)) {
//printf("type = %d\n", type);
if (type == CreateDir) {
t1->rootdirinodesize++;
t22->type1 = CreateDir;//设置索引类型(文件还是文件夹)
}
else if (type == CreateFile) {
t1->rootfileinodesize++;
t22->type1 = CreateFile;
}
}
else {
t1->rootdirinodesize++;//还没到最底层目录,必然是文件夹
t22->type1 = CreateDir;
}
t22->block_size = 1;//占据数据块数量
t22->block_num = 1;
int64 namelen = strlen(hdr->name[i]);
t22->name_len = namelen;//设置文件名长度
memcpy(type2buf2 + 128, hdr->name[i], namelen);//复制文件名
fputs_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));//写入配置信息
fputs_img(fp, offset, type2buf2, 512);//写入新索引信息
i++;
if (i == hdr->namesize) {
//printf("iiiiiiiiiiiiii=%d\n",i);
break;
}
else {
}
}
return offset;
}
//批量删除调用结构体
struct _Remove_Offset_Size {
int64 *offset_files;
int64 *offset_dirs;
int64 file_size;
int64 dir_size;
};
//动用该函数,必须确保,输入的偏移地址是文件夹
int64 FindDirNoX_ForRemove(FILE *fp, int64 roffset, char *dir, struct _Remove_Offset_Size *Nx) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
fgets_img(fp, roffset, type2buf, 512);
if (t2->down_type2 == 0) {
return 0;
}
char upname[1024];
memset(upname, 0, 1024);
memcpy(upname, type2buf + 128, strlen(type2buf + 128));
roffset = t2->down_type2;
char name[1024];
int64 i = 0;
while (1) {
if (roffset == 0)break;
fgets_img(fp, roffset, type2buf, 512);
if (strcmp(dir, "") == 0) {
memset(name, 0, 1024);
strcat(name, type2buf + 128);
}
else {
memset(name, 0, 1024);
strcat(name, dir);
strcat(name, "\\");
strcat(name, type2buf + 128);
}
if (t2->type1 == CreateDir) {
Nx->offset_dirs[Nx->dir_size] = roffset;
Nx->dir_size++;
FindDirNoX_ForRemove(fp, roffset, name,Nx);
}
else {
Nx->offset_files[Nx->file_size] = roffset;
Nx->file_size++;
//printf("FindDirNoX_ForRemove() dirname = %s\n", name);
//memset(name, 0, 1024);
//memcpy(name, type2buf + 128, t2->name_len);
//printf("FindDirNoX() upname = %s name = %s\n", upname, name);
//printf("FindDirNoX() upname = %s t2->name_len = %d\n", upname, t2->name_len);
}
roffset = moveoffset(fp, roffset, NE_OFF);
i++;
}
return 0;
}
//用于得到文件和文件夹数
int64 FindDirNoX_GetSize(FILE *fp, int64 roffset, char *dir,struct _Remove_Offset_Size *Nx) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
fgets_img(fp, roffset, type2buf, 512);
if (t2->down_type2 == 0) {
return 0;
}
char upname[1024];
memset(upname, 0, 1024);
memcpy(upname, type2buf + 128, strlen(type2buf + 128));
roffset = t2->down_type2;
char name[1024];
int64 i = 0;
while (1) {
if (roffset == 0)break;
fgets_img(fp, roffset, type2buf, 512);
if (strcmp(dir, "") == 0) {
memset(name, 0, 1024);
strcat(name, type2buf + 128);
}
else {
memset(name, 0, 1024);
strcat(name, dir);
strcat(name, "\\");
strcat(name, type2buf + 128);
}
if (t2->type1 == CreateDir) {
//printf("*filesize = %d\n", *offset_dirs);
Nx->dir_size++;
FindDirNoX_GetSize(fp, roffset, name,Nx);
}
else {
Nx->file_size++;
//printf("Nx->file_size = %d\n", Nx->file_size);
//printf("FindDirNoX_GetSize() dirname = %s\n", name);
//memset(name, 0, 1024);
//memcpy(name, type2buf + 128, t2->name_len);
//printf("FindDirNoX() upname = %s name = %s\n", upname, name);
//printf("FindDirNoX() upname = %s t2->name_len = %d\n", upname, t2->name_len);
}
roffset = moveoffset(fp, roffset, NE_OFF);
i++;
}
return 0;
}
//动用该函数,需确保输入的偏移地址是文件
int64 FindFileOffset_ForRemove(FILE *fp, int64 roffset, int64*offset_file) {
int i = 0;
while (1) {
if (roffset == 0)break;
offset_file[i] = roffset;
roffset = moveoffset(fp, roffset, DOWN_OFF);
i++;
}
return 0;
}
//批量释放数据块(既可用于文件也可用于文件夹)
int64 FreeOffset_ForRemove(FILE *fp,int64*offsets,int64 size) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
char type2buf1[2048];
memset(type2buf1, 0, 2048);
struct _MYIMG_TYPE2 *t21 = (struct _MYIMG_TYPE2 *)type2buf1;
int64 i = 0;
while (i<size) {
fgets_img(fp, offsets[i], type2buf, sizeof(struct _MYIMG_TYPE2));
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
t2->pr_type2 = t1->freeoffsetend;
t2->down_type2 = 0;//*
t2->up_type2 = 0;//*
fgets_img(fp, t1->freeoffsetend, type2buf1, sizeof(struct _MYIMG_TYPE2));
t21->ne_type2 = offsets[i];
fputs_img(fp, t1->freeoffsetend, type2buf1, sizeof(struct _MYIMG_TYPE2));
t1->freeoffsetend = offsets[i];
t1->freeinodesize++;
if (t2->type1 == CreateDir) {
t1->rootdirinodesize--;
}else if (t2->type1 == CreateFile) {
t1->rootfileinodesize--;
}
fputs_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
fputs_img(fp, offsets[i], type2buf, sizeof(struct _MYIMG_TYPE2));
i++;
}
return 0;
}
//移除节点与上级平级节点的关系(也可用于删除文件夹的)
int64 Removeoffset_ForRemove_UP_PR_NE(FILE*fp,int64 offset) {
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
char type2buf1[2048];
memset(type2buf1, 0, 2048);
struct _MYIMG_TYPE2 *t21 = (struct _MYIMG_TYPE2 *)type2buf1;
char type2buf2[2048];
memset(type2buf2, 0, 2048);
struct _MYIMG_TYPE2 *t22 = (struct _MYIMG_TYPE2 *)type2buf2;
fgets_img(fp, offset, type2buf, sizeof(struct _MYIMG_TYPE2));
if (t2->pr_type2 == 0) {
fgets_img(fp, t2->up_type2, type2buf1, sizeof(struct _MYIMG_TYPE2));
if (t2->ne_type2 == 0) {
t21->down_type2 = 0;
}
else {
t21->down_type2 = t2->ne_type2;
fgets_img(fp, t2->ne_type2, type2buf2, sizeof(struct _MYIMG_TYPE2));
t22->pr_type2 = 0;
fputs_img(fp, t2->ne_type2, type2buf2, sizeof(struct _MYIMG_TYPE2));
}
fputs_img(fp, t2->up_type2, type2buf1, sizeof(struct _MYIMG_TYPE2));
}
else {
fgets_img(fp, t2->pr_type2, type2buf1, sizeof(struct _MYIMG_TYPE2));
if (t2->ne_type2 == 0) {
t21->ne_type2 = 0;
}
else {
t21->ne_type2 = t2->ne_type2;
fgets_img(fp, t2->ne_type2, type2buf2, sizeof(struct _MYIMG_TYPE2));
t22->pr_type2 = t2->pr_type2;
fputs_img(fp, t2->ne_type2, type2buf2, sizeof(struct _MYIMG_TYPE2));
}
fputs_img(fp, t2->pr_type2, type2buf1, sizeof(struct _MYIMG_TYPE2));
}
return 0;
}
//用于批量删除文件时,调用的文件删除函数
int64 RemoveFile_s1(FILE*fp, int64 offset) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
char type2buf1[2048];
memset(type2buf1, 0, 2048);
struct _MYIMG_TYPE2 *t21 = (struct _MYIMG_TYPE2 *)type2buf1;
char type2buf2[2048];
memset(type2buf2, 0, 2048);
struct _MYIMG_TYPE2 *t22 = (struct _MYIMG_TYPE2 *)type2buf2;
int64 *offset_file;
fgets_img(fp, offset, type2buf, 512);
//它是文件
if (t2->type1 == CreateFile) {
int64 blocksize = NeedSuperBlock(t2->file_len);//通过文件长度,计算出共有多少数据块
offset_file = (int64*)malloc(sizeof(int64)*blocksize);//申请内存
FindFileOffset_ForRemove(fp, offset, offset_file);//搜寻文件对应的数据块
Removeoffset_ForRemove_UP_PR_NE(fp, offset);//解构文件头与上级文件夹同级文件/文件夹的关系
FreeOffset_ForRemove(fp, offset_file, blocksize);//释放所有数据块到空闲数据表
free(offset_file);
return 0;
}
else {
return -1;
}
}
int64 Remove(FILE*fp,char*dir) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
char type2buf1[2048];
memset(type2buf1, 0, 2048);
struct _MYIMG_TYPE2 *t21 = (struct _MYIMG_TYPE2 *)type2buf1;
char type2buf2[2048];
memset(type2buf2, 0, 2048);
struct _MYIMG_TYPE2 *t22 = (struct _MYIMG_TYPE2 *)type2buf2;
int64 *offset_file;
int64 roffset;
if (strcmp(dir, "") == 0) {
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
roffset = t1->rootoffset;
}
else {
roffset = HaveDir(fp, dir);
}
if (roffset <= 0)return -1;//不存在这个文件,返回报错
//这里,我得到的是一个目标偏移地址的,指向这个文件或文件夹
fgets_img(fp, roffset, type2buf, 512);
//它是文件
if (t2->type1 == CreateFile) {
int64 blocksize = NeedSuperBlock(t2->file_len);//通过文件长度,计算出共有多少数据块
offset_file = (int64*)malloc(sizeof(int64)*blocksize);
FindFileOffset_ForRemove(fp, roffset, offset_file);
Removeoffset_ForRemove_UP_PR_NE(fp,roffset);
FreeOffset_ForRemove(fp, offset_file, blocksize);
free(offset_file);
return 0;
}
else if(t2->type1 == CreateDir){
struct _Remove_Offset_Size Nx;
Nx.file_size = 0;
Nx.dir_size = 0;
FindDirNoX_GetSize(fp, roffset, dir,&Nx);
//printf("*filesize = %d\n", dirsize);
Nx.offset_files = (int64*)malloc(sizeof(int64)*Nx.file_size);
Nx.offset_dirs = (int64*)malloc(sizeof(int64)*Nx.dir_size);
int64 x= Nx.file_size, y= Nx.dir_size;
Nx.file_size = 0;
Nx.dir_size = 0;
FindDirNoX_ForRemove(fp, roffset, dir, &Nx);
if (Nx.dir_size == y && Nx.file_size == x) {
}
else { free(Nx.offset_dirs); free(Nx.offset_files); return -1; }//两次计算的文件和文件夹数量不一致
int64 i = 0;
while (i<Nx.file_size) {
RemoveFile_s1(fp, Nx.offset_files[i]);
i++;
}
FreeOffset_ForRemove(fp, Nx.offset_dirs, Nx.dir_size);
if (strcmp(dir, "") == 0) {
//根节点不能删的
fgets_img(fp, roffset, type2buf1, sizeof(struct _MYIMG_TYPE2));
t21->down_type2 = 0;
fputs_img(fp, roffset, type2buf1, sizeof(struct _MYIMG_TYPE2));
}
else {
//删除文件夹本身
Removeoffset_ForRemove_UP_PR_NE(fp, roffset);
FreeOffset_ForRemove(fp, &roffset, 1);
}
free(Nx.offset_dirs);
free(Nx.offset_files);
}
}
int64 Rename(FILE*fp, char*olddir,char*newdir) {
char buf[4096];
memset(buf, 0, 4096);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[4096];
memset(type2buf, 0, 4096);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
char type2buf1[4096];
memset(type2buf1, 0, 4096);
struct _MYIMG_TYPE2 *t21 = (struct _MYIMG_TYPE2 *)type2buf1;
char type2buf2[4096];
memset(type2buf2, 0, 4096);
struct _MYIMG_TYPE2 *t22 = (struct _MYIMG_TYPE2 *)type2buf2;
if (strcmp(olddir, "") == 0)return -1;//移动路径,源路径和目的路径都不能是根目录
if (strcmp(newdir, "") == 0)return -1;
if (strcmp(newdir, olddir) == 0)return -1;//新旧路径不能相同
int64 roldoffset = HaveDir(fp, olddir);
if (roldoffset <= 0)return -1;//源路径不存在
int64 rnewoffset= HaveDir(fp,newdir);
if (rnewoffset <= 0) {
//新路径不存在
fgets_img(fp, roldoffset, type2buf1, 4096);
if (t21->type1 == CreateDir) {
CreateDir2(fp, newdir, CreateDir);//调用函数创建路径
}
else if (t21->type1 == CreateFile) {
CreateDir2(fp, newdir, CreateFile);//调用函数创建路径
}
else {
return -1;
}
rnewoffset = HaveDir(fp, newdir);
if (rnewoffset <= 0)return -1;
fgets_img(fp, rnewoffset, type2buf2, 4096);
fgets_img(fp, roldoffset, type2buf1, 4096);
t22->file_len = t21->file_len;//文件长度
t22->down_type2 = t21->down_type2;//下级偏移地址,移交
//t22->name_len = t21->name_len;//文件名长度
t22->block_size = t21->block_size;//块数
memcpy(type2buf2+ 512, type2buf1+ 512, 4096 - 512);//复制可能存在的数据(文件名不要复制,要改的就是文件名)
t21->down_type2 = 0;//下级偏移地址置空
fputs_img(fp, rnewoffset, type2buf2, 4096);
fputs_img(fp, roldoffset, type2buf1, 4096);//写入新状态到数据块
Removeoffset_ForRemove_UP_PR_NE(fp, roldoffset);//解构旧索引的上下级关系
FreeOffset_ForRemove(fp, &roldoffset, 1);//释放旧索引占据的iNode,将其放回空闲表
return 0;
}
else {
return -1;//新路径不能已存在
}
}
int64 FindDirNoX(FILE *fp, int64 roffset,char *dir) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
fgets_img(fp, roffset, type2buf, 512);
if (t2->down_type2 == 0) {
return 0;
}
char upname[1024];
memset(upname, 0, 1024);
memcpy(upname, type2buf + 128, strlen(type2buf + 128));
roffset = t2->down_type2;
char name[1024];
int64 i = 0;
while (1) {
if (roffset == 0)break;
fgets_img(fp, roffset, type2buf, 512);
if (strcmp(dir, "") == 0) {
memset(name, 0, 1024);
strcat(name, type2buf + 128);
}
else {
memset(name, 0, 1024);
strcat(name, dir);
strcat(name, "\\");
strcat(name, type2buf + 128);
}
if (t2->type1 == CreateDir) {
FindDirNoX(fp, roffset, name);
}
else {
//memset(name, 0, 1024);
//memcpy(name, type2buf + 128, t2->name_len);
//printf("FindDirNoX() upname = %s name = %s\n", upname, name);
//printf("FindDirNoX() upname = %s t2->name_len = %d\n", upname, t2->name_len);
}
printf("FindDirNoX() dirname = %s\n", name);
roffset = moveoffset(fp, roffset, NE_OFF);
i++;
}
return 0;
}
int64 FindDirNo1(FILE *fp,char *dir) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
int64 roffset;
if (strcmp(dir, "") == 0) {
//空路径,表示根目录开始
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));//查找配置表
roffset = t1->rootoffset;//赋值根目录伪文件夹偏移地址(根目录是有实体的,一个iNode节点,类型为文件夹类型)
if (roffset == 0)return -1;
}
else {
roffset = HaveDir(fp, dir);//函数判断,是否存在路径,存在则返回偏移地址
if (roffset <= 0)return -1;
}
FindDirNoX(fp,roffset,dir);
return 0;
}
//创建文件夹(已存在不可创建)
int64 smkdir(FILE *fp, char *dir) {
int64 ret = HaveDir(fp, dir);
if (ret > 0)return -1;//文件夹已存在
return CreateDir2(fp, dir, CreateDir);
}
//用于打开文件的参数传递
struct _FOPEN_TYPE {
unsigned char data[4096];//缓冲区,读写文件,如果直接从文件当中读取,读写就太频繁了,效率低,还对硬盘不好(这话说的,你前面那一大堆函数就
对硬盘好了吗?)
int64 iNodeOffset;//指向文件的iNode块
int64 DataOffset;//指向正在读写的数据块
int64 DataLen;//文件总长度(读状态时,seeklen不可超过DataLen;写状态时,每写完一个数据块需要修正DataLen,关闭文件时需要保存DataLen)
int64 seeklen;
unsigned char *p;//data[4096]内,读取到的位置
int pn;//p指针偏移数据区域的偏移距离
int blockwritesize;//当前块被写入数量
};
int savefile(FILE *fp, struct _FOPEN_TYPE * ft) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[4096];
memset(type2buf, 0, 4096);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
//满足改条件,表示文件有未保存修改
if (ft->blockwritesize > 0) {
fputs_img(fp, ft->DataOffset, ft->data, 4096);
if (ft->seeklen > ft->DataLen) {
fgets_img(fp, ft->iNodeOffset, type2buf, 4096);
t2->file_len = ft->seeklen;
fputs_img(fp, ft->iNodeOffset, type2buf, 4096);
}
ft->blockwritesize = 0;
}
return 0;
}
int sfclose(FILE *fp, struct _FOPEN_TYPE * ft) {
//关闭文件,我并不知道,这个文件时被读过还是被写过
//但是不管是被读过,还是被写过,将缓冲区的数据全部写入到对应数据块,这样的操作是没有错误的
savefile(fp, ft);//先调用保存函数,将当前块写入的未保存数据,保存到磁盘
free(ft);//释放参数结构体
return 0;
}
char sfputc_use_buf[1024];
char sfputc_use_type2buf1[4096];
char sfputc_use_type2buf2[128];
int sfputc(FILE *fp,struct _FOPEN_TYPE * ft,int c) {
char *buf = sfputc_use_buf;
//memset(buf, 0, 1024);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
//char type2buf[4096];
//memset(type2buf, 0, 4096);
//struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
struct _MYIMG_TYPE2 *t2;
char *type2buf1= sfputc_use_type2buf1;
memset(type2buf1, 0, 4096);
struct _MYIMG_TYPE2 *t21 = (struct _MYIMG_TYPE2 *)type2buf1;
char *type2buf2= sfputc_use_type2buf2;
//memset(type2buf2, 0, 128);
struct _MYIMG_TYPE2 *t22 = (struct _MYIMG_TYPE2 *)type2buf2;
*ft->p = c;
//printf("*ft->p = %d\n", *ft->p);
ft->p++;
ft->seeklen++;
ft->pn++;//指针偏移距离加1
ft->blockwritesize++;//写入字符数加1
if (ft->pn == 3584) {
if (ft->seeklen >= ft->DataLen) {
//获取新数据块
int64 iNode = GetiNodeBiuld(fp);
if (iNode <= 0)return -1;
//镜像配置信息更改
fgets_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
t1->rootfileinodesize++;
fputs_img(fp, 0, buf, sizeof(struct _MYIMG_TYPE1));
//当前数据块更改配置
t2 = (struct _MYIMG_TYPE2 *)ft->data;
t2->down_type2 = iNode;
fputs_img(fp, ft->DataOffset, ft->data, 4096);
//文件信息更改配置
fgets_img(fp, ft->iNodeOffset, type2buf2, 128);
t22->file_len = ft->seeklen;
t22->block_size++;
fputs_img(fp, ft->iNodeOffset, type2buf2, 128);
//新数据块更改配置
fgets_img(fp, iNode, type2buf1, 4096);
t21->up_type2 = ft->DataOffset;
t21->type1 = CreateFile;
t21->block_num = t22->block_size;
fputs_img(fp, iNode, type2buf1, 4096);
//读写结构体,更改信息
ft->DataOffset = iNode;
ft->blockwritesize = 0;
memcpy(ft->data, type2buf1, 4096);
ft->DataLen = ft->seeklen;
ft->p = ft->data + 512;
ft->pn = 0;
}
else {
//当前数据块更改配置
t2 = (struct _MYIMG_TYPE2 *)ft->data;
fputs_img(fp, ft->DataOffset, ft->data, 4096);
//读写结构体,更改信息
ft->DataOffset = t2->down_type2;
ft->blockwritesize = 0;
fgets_img(fp, ft->DataOffset, ft->data, 4096);
ft->p = ft->data + 512;
ft->pn = 0;
}
}
return 0;
}
int sfgetc(FILE *fp, struct _FOPEN_TYPE * ft) {
if (ft->seeklen == ft->DataLen) {
//printf("seeklen = %d\n", ft->seeklen);
return -1;//当文件当前位置偏移距离等于文件长度时,文件读取完毕
}
int c = *ft->p;
ft->p++;
ft->pn++;
ft->seeklen++;
if (ft->pn == 3584) {
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)ft->data;
ft->DataOffset = t2->down_type2;//向下移动一个块
fgets_img(fp, ft->DataOffset, ft->data, 4096);
ft->p = ft->data + 512;
ft->pn = 0;
}
return c;
}
//仿fopen的功能,山寨货
struct _FOPEN_TYPE * sfopen(FILE *fp, char *dir,const char *type) {
char type2buf[128];
//memset(type2buf, 0, 128);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
int64 roffset;
struct _HaveDirRet hdr;
if (strcmp(type, "wb+") == 0) {
//不存在则创建文件,存在则删除文件
roffset = HaveDirRet(fp,&hdr,dir);
if (roffset <= 0) {
roffset = CreateDir3(fp, &hdr, dir, CreateFile);//这个路径不存在文件,创建一个新文件
}
else {
Remove(fp, dir);//先删除这个文件
roffset = CreateDir2(fp, dir, CreateFile);//再创建新文件
}
//roffset = HaveDir(fp, dir);
struct _FOPEN_TYPE *ft = (struct _FOPEN_TYPE*)malloc(sizeof(struct _FOPEN_TYPE));
ft->iNodeOffset = roffset;
fgets_img(fp, ft->iNodeOffset, type2buf, sizeof(struct _MYIMG_TYPE2));
ft->DataOffset = roffset;
ft->DataLen = t2->file_len;
ft->seeklen = 0;
fgets_img(fp, ft->DataOffset, ft->data, 4096);//将整个当前读写的块,读入缓冲区
ft->p = ft->data + 512;//前512字节是iNode和文件名的存储空间
ft->pn = 0;
ft->blockwritesize = 0;
return ft;//返回该文件偏移地址
}
else if (strcmp(type, "ab+") == 0) {
//文件存在,不重新创建文件,直接返回得到的偏移地址;文件不存在,创建文件,返回偏移地址
roffset = HaveDir(fp, dir);
if (roffset <= 0) {
roffset = CreateDir2(fp, dir, CreateFile);//这个路径不存在文件,创建一个新文件
roffset = HaveDir(fp, dir);
}
struct _FOPEN_TYPE *ft = (struct _FOPEN_TYPE*)malloc(sizeof(struct _FOPEN_TYPE));
ft->iNodeOffset = roffset;
ft->DataOffset = moveoffset_toend(fp, ft->iNodeOffset, DOWN_OFF);
fgets_img(fp, ft->iNodeOffset, type2buf, sizeof(struct _MYIMG_TYPE2));
ft->DataLen = t2->file_len;
ft->seeklen = t2->file_len;
fgets_img(fp, ft->DataOffset, ft->data, 4096);//将整个当前读写的块,读入缓冲区
ft->pn = ft->DataLen % 3584;//求得当前读写长度除3584(即每个块的存储容量)的余数,这个余数就是p指针距离偏移数据区域开头的偏移距离
ft->p = ft->data + 512 + ft->pn;
ft->blockwritesize = 0;
return ft;
}
else if (strcmp(type, "w+") == 0) {
return NULL;//暂不支持(对于怎么实现写txt文档,我还真没注意过,之前一直用Windows提供的API)
}
else if (strcmp(type, "r+") == 0) {
return NULL;//暂不支持
}
else if (strcmp(type, "a+") == 0) {
return NULL;//暂不支持
}
else {
return NULL;//该类型无法识别
}
}
int64 sfseek(FILE *fp, struct _FOPEN_TYPE * ft,int64 offset,char type) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
fgets_img(fp, ft->iNodeOffset, type2buf, sizeof(struct _MYIMG_TYPE2));
if (t2->type1 == CreateFile) {
if (type == 0) {
//距离文件开头,偏移offset
if (offset == 0) {
ft->p = ft->data + 512;
ft->pn = 0;
ft->DataLen = t2->file_len;
ft->seeklen = 0;
ft->DataOffset = ft->iNodeOffset;
fgets_img(fp, ft->DataOffset, ft->data, 4096);
ft->blockwritesize = 0;
return 0;
}
else {
if (offset < 0)return -1;//负向移动会超出边界
if (offset > t2->file_len)return -1;//超出边界(文件没有那么长)
ft->pn = offset % 3584;
//1个数据块 1-3584 p写完3583,移动到下一个数据块数据区域的0 pn+1为3584 DataLen+1 %3584为0
int64 x = (offset - ft->pn) / 3584;//计算出,需要经过几次跳跃数据块,才能到达对应数据块
int64 i = 0;
ft->DataOffset = ft->iNodeOffset;
while (i < x) {
ft->DataOffset = moveoffset(fp, ft->DataOffset, DOWN_OFF);//向下移动x次
i++;
}//循环结束,得到的是一个指向offset所在的块
ft->seeklen = offset;
ft->DataLen = t2->file_len;
ft->p = ft->data + 512 + ft->pn;
fgets_img(fp, ft->DataOffset, ft->data, 4096);
ft->blockwritesize = 0;
return 0;
}
}
else if (type == 1) {
//距离当前位置,偏移offset
return -1;//我懒,不想动,反正也用不上
}
else if (type == 2) {
//距离文件末尾,偏移offset
if ((offset + t2->file_len) < 0)return -1;//在开头位置超出边界
if (offset > 0)return -1;//正向移动会超出边界
ft->pn = (t2->file_len + offset) % 3584;
ft->p = ft->data + 512 + ft->pn;
ft->seeklen = t2->file_len + offset;
int64 x = ((t2->file_len + offset) - ft->pn) / 3584;
int64 i = 0;
ft->DataOffset = ft->iNodeOffset;
while (i < x) {
ft->DataOffset = moveoffset(fp, ft->DataOffset, DOWN_OFF);
i++;
}
fgets_img(fp, ft->DataOffset, ft->data, 4096);
ft->blockwritesize = 0;
return 0;
}
else {
return -1;
}
}
else {
return -1;//不是文件
}
}
FILE * CreateMYIMG(const char *dir,int64 len) {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
FILE *fp1 = fopen(dir, "wb+");
if (fp1 == NULL) {
return NULL;
}
else {
fputs_img(fp1, 0, buf,1024);//创建1024字节作为配置区域
t1->datalen = 0;
t1->headlen = 1024;
t1->imglen1 = fileLen(fp1);
t1->imglen2 = len;//虚拟大小是1024G(当然,实际上是不存在的这么大的)
t1->freeinodesize = 0;
t1->freeoffset = 0;//初始化前,一个数据块都没有,所以空闲iNode表为空
t1->freeoffsetend = 0;
t1->rootoffset = 0;//初始化前,根目录下没有任何数据,所以文件表为空
fputs_img(fp1, 0, buf, sizeof(struct _MYIMG_TYPE1));//将配置信息存入文件开头
//printf("t1->imglen2 = %I64d\n", t1->imglen2);
int64 getoffset = GetiNodeBiuld(fp1);
//printf("getoffset = %I64d\n", getoffset);
getoffset = GetiNodeBiuld(fp1);//使根目录有一个实体索引
fgets_img(fp1, 0, buf, sizeof(struct _MYIMG_TYPE1));
t1->rootinodesize++;
t1->rootoffset = getoffset;
t2->type1 = CreateDir;//类型是CreateDir,认为是文件夹
fputs_img(fp1, 0, buf, sizeof(struct _MYIMG_TYPE1));
fputs_img(fp1, getoffset, type2buf, sizeof(struct _MYIMG_TYPE2));
//fclose(fp1);
}
return fp1;
}
FILE * OpenMYIMG(const char *dir) {
FILE *fp1 = fopen(dir, "ab+");
if (fp1 == NULL) {
return NULL;
}
else {
return fp1;
}
}
int CloseMYIMG(FILE *fp1) {
fclose(fp1);
return 0;
}
struct _DIR_ {
char dir[512];
struct _DIR_ *pNext;
};
struct _DIR_ *list;
int maxlen = 0;
int foundfile2(char *dir) {
int64 Handle;
struct _finddata_t FileInfo;
if ((Handle = _findfirst(dir, &FileInfo)) == -1L) {
//printf("没有找到匹配项目,文件夹不存在或文件夹为空!\n");
return 0;
}
char *_dir = (char *)malloc(sizeof(char)*strlen(dir));
char *__dir = (char *)malloc(sizeof(char)*strlen(dir));
int64 i = 0;
while (1) {
if (strcmp(FileInfo.name, (char*)".") != 0 && strcmp(FileInfo.name, (char*)"..") != 0) {
//文件夹
free(_dir);
_dir = (char *)malloc(sizeof(char)*((strlen(dir) - 3) + strlen(FileInfo.name) + 5 + 1));
char *__dir = (char *)malloc(sizeof(char)*((strlen(dir) - 3) + strlen(FileInfo.name) + 1));
memcpy(_dir, dir, strlen(dir) - 3);
memcpy(_dir + (strlen(dir) - 3), FileInfo.name, strlen(FileInfo.name));
memcpy(_dir + (strlen(dir) - 3) + strlen(FileInfo.name), "\\*.*", 5);
_dir[(strlen(dir) - 3) + strlen(FileInfo.name) + 5] = '\0';
memcpy(__dir, dir, strlen(dir) - 3);
memcpy(__dir + (strlen(dir) - 3), FileInfo.name, strlen(FileInfo.name));
__dir[strlen(dir) - 3 + strlen(FileInfo.name)] = '\0';
//printf("__dir = %s\n", __dir);
struct _stat buf;
int ret = _stat(__dir, &buf);
if ((buf.st_mode&S_IFDIR)>0) {
foundfile2(_dir);
}
else {
struct _DIR_ *dr=(struct _DIR_*)malloc(sizeof(struct _DIR_));
memset(dr->dir, 0, 512);
memcpy(dr->dir, __dir,strlen(__dir));
dr->pNext = list;
list = dr;
}
//printf("%s\n", __dir);
free(__dir);
i++;
}
if (_findnext(Handle, &FileInfo) != 0)break;
}
free(_dir);
free(__dir);
_findclose(Handle);//关闭
return 0;
}
//清理
struct _DIR_ * listClean(struct _DIR_ *start) {
struct _DIR_ *p1, *p2;
p1 = p2 = start;
while (1) {
if (p1 == NULL)break;
//printf("%d\n",p1->i);
p1 = p1->pNext;
free(p2);
p2 = p1;
}
return p1;
}
int mainNo1() {
char buf[2048];
memset(buf, 0, 2048);
struct _MYIMG_TYPE1 *t1 = (struct _MYIMG_TYPE1 *)buf;
char type2buf[2048];
memset(type2buf, 0, 2048);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
char dir[1024];
memset(dir, 0, 1024);
FILE*fp1 = CreateMYIMG("1.myiso", (int64)1 * 1024 * 1024 * 1024 * 1024);
//FILE*fp1 = OpenMYIMG("1.myiso");
sprintf(dir, "myname\\dir1\\dir2\\data\\d1.ios");
CreateDir2(fp1, dir, CreateFile);
sprintf(dir, "myname1\\dir1\\dir2\\data\\d2.ios");
CreateDir2(fp1, dir, CreateFile);
sprintf(dir, "myname2\\dir1\\dir2\\data\\dir1");
CreateDir2(fp1, dir, CreateDir);
//sprintf(dir, "myname\\dir1\\dir2\\data\\dir2");
//CreateDir2(fp1, dir, CreateDir);
//sprintf(dir, "myname\\dir1\\dir2\\data\\dir3");
//CreateDir2(fp1, dir, CreateDir);
//int64 ret = HaveDir(fp1, dir);
//printf("main() ret = %d\n", ret);
FindDirNo1(fp1, (char*)"");
fgets_img(fp1, 0, buf, 1024);
printf("main() t1->rootdirinodesize = %d\n", t1->rootdirinodesize);
printf("main() t1->rootfileinodesize = %d\n", t1->rootfileinodesize);
sprintf(dir, "");
//Remove(fp1, dir);
Rename(fp1, (char*)"myname1\\dir1\\dir2\\data\\d2.ios", (char*)"一个中文名\\二级的中文名\\三级目录\\继续\\应该差不多了.ios");
FindDirNo1(fp1, (char*)"");
fgets_img(fp1, 0, buf, 1024);
printf("main() t1->rootdirinodesize = %d\n", t1->rootdirinodesize);
printf("main() t1->rootfileinodesize = %d\n", t1->rootfileinodesize);
fgets_img(fp1, t1->rootoffset, type2buf, 512);
printf("main() t2->down_type2 = %d\n", t2->down_type2);
CloseMYIMG(fp1);
return 0;
}
int mainNo2() {
FILE*fp1 = CreateMYIMG("1.myiso", (int64)1 * 1024 * 1024 * 1024 * 1024);
smkdir(fp1, (char*)"name");
list = NULL;
foundfile2((char*)"D:\\新建文件夹\\*.*");
struct _DIR_ *p1;
for (p1 = list; p1 != NULL; p1 = p1->pNext) {
char *p = p1->dir + 3;
printf("%s\n", p);
FILE *fp2 = fopen(p1->dir, "rb");
struct _FOPEN_TYPE *ft1 = sfopen(fp1, p, "wb+");
int c;
while (1) {
c = fgetc(fp2);
//printf("c = %d\n", c);
if (c == -1)break;
sfputc(fp1, ft1, c);
}
sfclose(fp1, ft1);
fclose(fp2);
}
listClean(list);
list = NULL;
FindDirNo1(fp1, (char*)"");
CloseMYIMG(fp1);
return 0;
}
int64 strStr(void *haystack_input, void *needle_input) {
char *haystack, *needle;
char *charArrayHaystack = haystack = (char*)haystack_input;
char *charArrayNeedle = needle = (char*)needle_input;
if (strlen(needle) == 0)
return 0;
for (int64 i = 0; i < strlen(haystack); i++) {
if (charArrayHaystack[i] == charArrayNeedle[0]) {
int64 j = i + 1;//待匹配字符串的数组位置加1
int64 k = 1;//匹配字符串的数组位置加1
while (1) {
if (charArrayNeedle[k] == '\0')break;//如果匹配字符串到结尾,跳出循环
if (charArrayHaystack[j] == '\0')break;//如果待匹配字符串到结尾,跳出循环
if (charArrayHaystack[j] == charArrayNeedle[k]) {
j++; k++;//单个字符匹配,数组键值后移一位
}
else {
break;//单个字符不匹配,跳出循环
}
}
if (k == strlen(charArrayNeedle)) {
return i;//检查跳出循环后,已经检查匹配的字符数是否与匹配字符串长度一致,一致则返回该位置起始键值
}
}
}
return -1;//没有找到,返回-1
}
int dirCreate_forfile(char *dir) {
char _gang[] = "\\";
char *p1 = dir;
while (1) {
int key = strStr(p1, _gang);
if (key == -1)break;
p1[key] = '\0';
if ((_access(dir, 0)) != 0)
{
if (0 != mkdir(dir))//成功返回0,失败返回-1
{
return -1;
}
}
p1[key] = '\\';
p1 += (key + 1);
}
return 0;
}
int mainNo3() {
//FILE*fp1 = CreateMYIMG("1.myiso", (int64)1 * 1024 * 1024 * 1024 * 1024);
FILE*fp1 = OpenMYIMG("1.myiso");
//smkdir(fp1, (char*)"name");
//FindDirNo1(fp1, (char*)"");
list = NULL;
foundfile2((char*)"D:\\新建文件夹\\*.*");
struct _DIR_ *p1;
int64 errorfilesize = 0;//错误的文件数
int64 errorsize = 0;//错误的字节数(或者文件长度有误)
for (p1 = list; p1 != NULL; p1 = p1->pNext) {
char *p = p1->dir + 3;
printf("%s\n", p);
FILE *fp2 = fopen(p1->dir, "rb");
//dirCreate_forfile(p);
//FILE *fp3 = fopen(p, "wb");
struct _FOPEN_TYPE *ft1 = sfopen(fp1, p, "ab+");
sfseek(fp1, ft1, 0, 0);
printf("%d\n",ft1->iNodeOffset);
printf("%d\n", ft1->DataOffset);
printf("DataLen = %d\n", ft1->DataLen);
printf("seeklen = %d\n", ft1->seeklen);
int64 thisfileerrorsize = 0;
int c, ciso;
int i = 0;
while (1) {
c = fgetc(fp2);
if (c == -1)break;
ciso = sfgetc(fp1, ft1);
if (ciso == -1) { thisfileerrorsize++; errorsize++; break; }
if (c != ciso) {
thisfileerrorsize++;
errorsize++;
}
else {
//printf("%d\n", c);
}
//
i++;
//fputc(c, fp3);
//sfputc(fp1, ft1, c);
}
if (thisfileerrorsize > 0) {
errorfilesize++;
}
sfclose(fp1, ft1);
fclose(fp2);
//fclose(fp3);
}
listClean(list);
list = NULL;
FindDirNo1(fp1, (char*)"");
CloseMYIMG(fp1);
printf("errorfilesize = %d\n", errorfilesize);
printf("errorsize = %d\n", errorsize);
return 0;
}
int mainNo4() {
FILE*fp1 = CreateMYIMG("1.myiso", (int64)1 * 1024 * 1024 * 1024 * 1024);
smkdir(fp1, (char*)"name");
list = NULL;
foundfile2((char*)"D:\\新建文件夹\\*.*");
struct _DIR_ *p1;
for (p1 = list; p1 != NULL; p1 = p1->pNext) {
char *p = p1->dir + 3;
printf("%s\n", p);
//FILE *fp2 = fopen(p1->dir, "rb");
struct _FOPEN_TYPE *ft1 = sfopen(fp1, p, "wb+");
/*
int c;
while (1) {
c = fgetc(fp2);
//printf("c = %d\n", c);
if (c == -1)break;
sfputc(fp1, ft1, c);
}
*/
sfclose(fp1, ft1);
//fclose(fp2);
}
listClean(list);
list = NULL;
FindDirNo1(fp1, (char*)"");
/*
struct _HaveDirRet hdr;
int64 ret = HaveDirRet(fp1, &hdr, (char*)"新建文件夹\\mysql-connector-c++-8.0.13-win32.rar");
printf("ret=%d\n", ret);
printf("hdr.ret=%d\n", hdr.ret);
printf("name=%s\n", hdr.name[hdr.success_num]);
printf("success_num=%d\n", hdr.success_num);
printf("offset=%d\n", hdr.offset[hdr.success_num]);
printf("namesize=%d\n", hdr.namesize);
char type2buf[4096];
memset(type2buf, 0, 4096);
fgets_img(fp1, hdr.offset[hdr.success_num], type2buf, 4096);
struct _MYIMG_TYPE2 *t2 = (struct _MYIMG_TYPE2 *)type2buf;
printf("type1=%d\n", t2->type1);
printf("name=%s\n", type2buf+128);
*/
CloseMYIMG(fp1);
return 0;
}
int main() {
//logPuts("创建镜像并写入!");
//mainNo2();
//logPuts("写入完成!");
//logPuts("读取文件并核对!");
//mainNo3();
//logPuts("核对完成!");
logPuts("生成文件或文件夹测试开始!");
mainNo4();
logPuts("测试结束!");
while (1) { Sleep(1); }
//printf("%d\n", -100 % 3584);
//while (1);
while (1) {
Sleep(1);
}
return 0;
}