windows下当文件名长度超出系统限制时无法拷贝/删除的解决办法

默认情况下,windows下文件的完整路径长度限制是260,在目录下存在文件长度超出系统限制的情况下,删除或者拷贝目录都会失败,此时可通过robocopy命令来进行拷贝或者删除操作。

拷贝

robocopy sourceDir destinationDir /E


删除

1、创建个空目录:mkdir C:\emptyDir

2、删除要删除的目录:robocopy C:\emptyDir deleteDir /purge

3、删除创建的空目录:rmdir C:\emptyDir

#include <windows.h> #include <iostream> #include <stdlib.h> #include <string.h> #include <time.h> #include <stdio.h> // 添加文件操作相关头文件 using namespace std; #include <vector> #include <string> // 目录项结构定义 struct DirectoryEntry { std::string filename; int cluster; // 其他需要的字段... }; class Directory { private: std::vector<DirectoryEntry> entries; int maxFileCount; // 可选:如果需要限制最大文件数 public: Directory(int maxCount = 100) : maxFileCount(maxCount) { entries.reserve(maxCount); // 预分配空间 } // 添加目录项 bool addEntry(const DirectoryEntry& entry) { if (entries.size() >= maxFileCount) { return false; // 目录已满 } entries.push_back(entry); return true; } }; #define FILENAME_LEN 3 // 文件名长度 #define SHELL_LEN 5 // 命令动词长度 #define ShellCount 6 // 命令种类 char *path = "disk.txt"; // 保存磁盘文件 char *shellstr[ShellCount] = {"dir", "cre", "del", "dis", "fat", "exit"}; // 文件目录结构:文件名3B,文件属性1B,长度2B,起始簇号2B #define HPC 4 // 每柱面磁道数 #define SPT 16 // 每磁道的扇区数 #define Cylinders 64 // 柱面数 #define SectorSize 128 // 扇区大小 #define DirSize 16 // 根目录大小(扇区),占16扇区 int Maxfilecount = DirSize * SectorSize / 8; // 存放的最大文件数 // FAT表占用的扇区数和开始扇区号 int FatSize = ((HPC * SPT * Cylinders * 2) % SectorSize == 0)? (HPC * SPT * Cylinders * 2) / SectorSize : (HPC * SPT * Cylinders * 2) / SectorSize + 1; int FatBegin = DirSize; // 位示图占用的扇区数和开始扇区号 int BitMapSize = ((HPC * SPT * Cylinders / 8) % SectorSize == 0)? (HPC * SPT * Cylinders / 8) / SectorSize : (HPC * SPT * Cylinders / 8) / SectorSize + 1; int BitMapBegin = DirSize + FatSize; int DataBeginSector = DirSize + FatSize + BitMapSize; // 存放数据起始扇区号 unsigned short Memory = 0; // 空闲盘块数 unsigned char DISK[Cylinders][HPC][SPT][SectorSize]; // 磁盘大小 unsigned short FAT[HPC * SPT * Cylinders]; // 内存FAT表 unsigned short bitmap[HPC * SPT * Cylinders / 16]; // 内存位示图 unsigned char Dir[DirSize * SectorSize]; // 内存目录 unsigned char filecon[1024]; // 文件内容 // 目录项结构定义 typedef struct { unsigned char name[3]; // 文件名 unsigned char attr; // 文件属性 unsigned short length; // 长度 unsigned short first_cluster; // 起始簇号 } DirectoryEntry; // 功能:错误命令处理 // id:错误代码 void errorp(int id) { // 错误命令处理函数 switch (id) { case 0: puts("文件不存在!"); break; case 1: puts("文件/目录已存在!"); break; case 2: puts("语法不正确!"); break; case 3: puts("不存在命令!"); break; case 4: puts("存储空间不够!"); break; case 5: puts("文件名太长!"); break; case 6: puts("无空闲目录!"); break; case 7: puts("操作命令太长!"); break; default: puts("无效命令!"); } } // 功能:如果位示图第n位为1则返回真,为0返回假 bool getbitmap(int n) { return bool(bitmap[n / 16] & (1 << (n % 16))); } // 功能:初始化位示图和FAT void initbitmap() { int i; int k1 = HPC * SPT * Cylinders - DataBeginSector; int k2 = (k1 % 16 == 0)? k1 / 16 : k1 / 16 + 1; for (i = 0; i < k2; i++) bitmap[i] = (rand() * 3) % 65536; for (i = 0; i < k1; i++) if (getbitmap(i) == 0) { Memory++; FAT[i] = 0; } else FAT[i] = -1; } // 功能:显示位示图 void showbitmap() { int i; // int k=HPC*SPT*Cylinders-DataBeginSector;//显示全部位图 int k = 128; // 显示部分位图 cout << "位示图:" << endl; for (i = 0; i < k; i++) { printf("%d ", bool(bitmap[i / 16] & (1 << (i % 16)))); if (i % 16 == 15) cout << endl; } cout << endl; } // 功能:显示FAT void showfat() { int i; // int k=HPC*SPT*Cylinders;//显示全部FAT int k = 128; // 显示部分FAT cout << "FAT表:" << endl; for (i = 0; i < k; i++) { printf("%-8d", FAT[i]); if (i % 8 == 7) cout << endl; } cout << endl; } // 功能:将位示图中的第n位设成k状态 void setbitmap(int n, int k) { if (k) bitmap[n / 16] = bitmap[n / 16] | (1 << (n % 16)); else bitmap[n / 16] = bitmap[n / 16] & ~(1 << (n % 16)); } // 功能:从内存Dir[]开始查找str目录结点并返回str节点指针,如没查到则返回NULL。 // str:文件名 unsigned char *find(char *str) { unsigned char *p = (unsigned char *)directory; bool mark; unsigned short j; if (str[0] == '\0') return NULL; for (int i = 0; i < Maxfilecount; i++) { if (*p != '\0') { // 目录不空对比 mark = true; for (j = 0; j < strlen(str); j++) { if (*(str + j) != *(p + j)) { mark = false; break; } } if ((mark == true && j == FILENAME_LEN) || (mark == true && j < FILENAME_LEN && *(p + j) == '\0')) return p; } p += sizeof(DirectoryEntry); } return NULL; } // 功能:将p后的长度为SectorSize字符串写到ls扇区中 // 如果字符串长度小于SectorSize,则写实际长度 void writedisk(unsigned char *p, int ls) { int C, H, S; C = ls / (HPC * SPT); // 计算柱面号 H = (ls / SPT) % HPC; // 计算磁头号 S = ls % SPT; // 计算扇区号 int realSize = strlen((char *)p) < SectorSize? strlen((char *)p) : SectorSize; for (int i = 0; i < realSize; i++) { DISK[C][H][S][i] = *(p + i); } if (realSize < SectorSize) { for (int i = realSize; i < SectorSize; i++) { DISK[C][H][S][i] = '\0'; } } } // 功能:将ls扇区中长度为size的字符串读到字符型指针p中 void readdisk(unsigned char *p, int ls, int size) { int C, H, S; C = ls / (HPC * SPT); // 计算柱面号 H = (ls / SPT) % HPC; // 计算磁头号 S = ls % SPT; // 计算扇区号 for (int i = 0; i < size; i++) *(p + i) = DISK[C][H][S][i]; } // 查找空闲簇 unsigned short find_free_cluster() { // 跳过簇0和簇1(保留簇) for (unsigned short i = 2; i < HPC * SPT * Cylinders; i++) { if (FAT[i] == 0) { // 0表示空闲簇 return i; } } return 0; // 没有可用簇 } // 初始化程序 void init() { int i = 0; FILE *fp1; unsigned char *tmp = &DISK[0][0][0][0]; fp1 = fopen(path, "rb"); if (fp1 == NULL) // 第一次运行该程序 initbitmap(); else { while (!feof(fp1)) { *(tmp + i) = fgetc(fp1); i++; } fclose(fp1); // 将磁盘根目录读到Dir[]中,便于操作 unsigned char *p = Dir; for (i = 0; i < DirSize; i++) { readdisk(p, i, SectorSize); p += SectorSize; } // 将FAT表读入内存FAT[]中 unsigned short *p1 = FAT; for (i = 0; i < FatSize; i++) { readdisk((unsigned char *)p1, i + FatBegin, SectorSize); p1 += SectorSize / 2; } // 将bitmap表读入内存bitmap[]中 p1 = bitmap; for (i = 0; i < BitMapSize; i++) { readdisk((unsigned char *)p1, i + BitMapBegin, SectorSize); p1 += SectorSize / 2; } int k1 = HPC * SPT * Cylinders - DataBeginSector; for (i = 0; i < k1; i++) if (getbitmap(i) == 0) Memory++; } } // 程序运行完后保存磁盘DISK到文件中 void save() { int i = 0; FILE *fp1; // 将内存Dir[]写到DISK中,然后用文件的方式保存 unsigned char *p = Dir; for (i = 0; i < DirSize; i++) { writedisk(p, i); p += SectorSize; } // 将内存FAT[]表写入DISK中 unsigned short *p1 = FAT; for (i = 0; i < FatSize; i++) { writedisk((unsigned char *)p1, i + FatBegin); p1 += SectorSize / 2; } // 将内存bitmap[]写到DISK中 p1 = bitmap; for (i = 0; i < BitMapSize; i++) { writedisk((unsigned char *)p1, i + BitMapBegin); p1 += SectorSize / 2; } // 将DISK保存在磁盘文件中 unsigned char *tmp = &DISK[0][0][0][0]; fp1 = fopen(path, "wb"); if (fp1 == NULL) cout << "无法写入文件!"; else { for (i = 0; i < Cylinders * HPC * SPT * SectorSize; i++) fputc(*(tmp + i), fp1); fclose(fp1); } } // 功能:显示str目录内容 // str:可以采用绝对或相对路径 bool direxc(char *str) { int i, j; char *dirstr[2] = { "<file>", "<dir>" }; // showbitmap(); unsigned char *p = (unsigned char *)directory; char filename[4]; unsigned short length, start; cout << "文件名 类型 长度 起始块号" << endl; for (i = 0; i < Maxfilecount; i++) { if (*p != '\0') { // 目录不空显示 for (j = 0; j < 3; j++) filename[j] = *(p + j); filename[j] = '\0'; length = ((DirectoryEntry *)p)->length; start = ((DirectoryEntry *)p)->first_cluster; printf("%6s %6s %5u%5u\n", filename, dirstr[((DirectoryEntry *)p)->attr], length, start); } p += sizeof(DirectoryEntry); } printf("磁盘剩余空间为:%d字节 \n", Memory * SectorSize); return true; } // 自动生成文件内容,并返回文件长度 int createcon(unsigned char *con) { int i; while (1) { printf("请输入创建文件长度(1025B以下):"); scanf("%d", &i); if (i > 0 && i < 1025) break; fflush(stdin); } for (int k = 0; k < i; k++, con++) *con = 32 + rand() % 95; *con = '\0'; return i; } // 查找第一个空白目录 unsigned char *findfirstemptyDir() { unsigned char *p = (unsigned char *)directory; for (int i = 0; i < Maxfilecount; i++) if (*p == '\0') return p; else p += sizeof(DirectoryEntry); return NULL; } // 功能:将文件名写到目录中,最多3个字符, // 如果文件名少于3个字符,则后面加'\0' // p:目录开始指针,file:文件名指针 void writefilename(unsigned char *p, char *file) { unsigned short i, k; k = strlen(file); for (i = 0; i < k; i++) { *p = (unsigned char)*file; p++; file++; } if (k < 3) *p = '\0'; } // 功能:创建str文件 // 流程:分配块,写数据,更新fat表。 // str:可以采用绝对或相对路径 bool creexc(char *str) { unsigned short i, j, k; short l; int length; unsigned char *tmp = find(str); unsigned char *p = filecon; if (tmp != NULL) // 文件已经存在 { errorp(1); return false; } else { // 1. 查找空闲目录项 for (i = 0; i < Maxfilecount; i++) { if (((DirectoryEntry *)&directory[i])->name[0] == 0x00) { // 找到空闲目录项 break; } } if (i == Maxfilecount) { // 没有空闲目录项 errorp(6); return false; } // 2. 生成文件内容 length = createcon(filecon); if (length <= 0) { errorp(6); // 文件长度错误 return false; } // 3. 分配磁盘块并写入数据 unsigned short first_cluster = 0; unsigned short current_cluster = 0; unsigned short next_cluster = 0; int bytes_written = 0; // 分配第一个簇 first_cluster = find_free_cluster(); if (first_cluster == 0) { errorp(4); // 磁盘空间不足错误 return false; } current_cluster = first_cluster; // 写入数据到磁盘块 while (bytes_written < length) { // 计算当前簇能写入的字节数(每簇4字节) int bytes_to_write = (length - bytes_written > 4)? 4 : length - bytes_written; // 写入数据到磁盘块 unsigned char buffer[4]; memcpy(buffer, &filecon[bytes_written], bytes_to_write); writedisk(buffer, current_cluster); bytes_written += bytes_to_write; // 如果还有数据需要写入,分配下一个簇 if (bytes_written < length) { next_cluster = find_free_cluster(); if (next_cluster == 0) { // 回滚已分配的簇 while (current_cluster != first_cluster) { unsigned short prev_cluster = current_cluster; current_cluster = find_prev_cluster(prev_cluster); FAT[prev_cluster] = 0; // 释放簇 Memory++; } FAT[first_cluster] = 0; // 释放第一个簇 Memory++; errorp(4); // 磁盘空间不足错误 return false; } // 更新FAT表,链接到下一个簇 FAT[current_cluster] = next_cluster; current_cluster = next_cluster; } } // 标记最后一个簇为文件结束 FAT[current_cluster] = 0xFFFF; // 表示文件结束 // 4. 更新目录项 DirectoryEntry *dir_entry = &directory[i]; memcpy(dir_entry->name, str, 3); dir_entry->attr = 0; // 普通文件 dir_entry->length = length; dir_entry->first_cluster = first_cluster; // 5. 保存更新后的目录和FAT表到磁盘 save(); printf("文件创建成功,大小: %d 字节\n", length); return true; } return true; } // 查找前一个簇(用于回滚操作) unsigned short find_prev_cluster(unsigned short cluster) { for (unsigned short i = 2; i < HPC * SPT * Cylinders; i++) { if (FAT[i] == cluster) { return i; } } return 0; // 没有找到前一个簇 } // 功能:删除文件或目录 // 释放磁盘块,清空目录项 // str:文件名 void delexc(char *str) { unsigned char *tp = find(str); if (tp != NULL) { // 1. 找到文件在目录中的索引 int dir_index = (tp - (unsigned char *)directory) / sizeof(DirectoryEntry); // 2. 获取文件的第一个簇 unsigned short current_cluster = directory[dir_index].first_cluster; // 3. 释放文件占用的所有簇 while (current_cluster != 0xFFFF && current_cluster != 0) { unsigned short next_cluster = FAT[current_cluster]; FAT[current_cluster] = 0; // 释放簇 Memory++; // 增加空闲空间计数 current_cluster = next_cluster; } // 4. 清空目录项 memset(&directory[dir_index], 0, sizeof(DirectoryEntry)); // 5. 保存更新后的目录和FAT表 save(); printf("文件删除成功\n"); } else errorp(0); } // 功能:显示文件内容 // str:文件名 void disexc(char *str) { unsigned char *tp = find(str); if (tp != NULL) { // 1. 找到文件在目录中的索引 int dir_index = (tp - (unsigned char *)directory) / sizeof(DirectoryEntry); // 2. 获取文件信息 unsigned short current_cluster = directory[dir_index].first_cluster; unsigned short file_size = directory[dir_index].length; // 3. 读取文件内容 int bytes_read = 0; unsigned char *p = filecon; memset(filecon, 0, sizeof(filecon)); // 清空文件内容缓冲区 while (current_cluster != 0xFFFF && current_cluster != 0 && bytes_read < file_size) { // 计算当前簇要读取的字节数 int bytes_to_read = (file_size - bytes_read > 4)? 4 : file_size - bytes_read; // 从磁盘读取数据 unsigned char buffer[4]; readdisk(buffer, current_cluster, bytes_to_read); memcpy(p, buffer, bytes_to_read); p += bytes_to_read; bytes_read += bytes_to_read; // 获取下一个簇 current_cluster = FAT[current_cluster]; } *p = '\0'; // 添加字符串结束符 cout << filecon << endl; } else errorp(0); } // 功能:显示部分FAT和位示图内容 // str:文件名 void fatexc() { showbitmap(); showfat(); } void menu() { // 显示命令菜单 printf("有下列命令可供使用:\n"); printf("[1] dir 显示目录内容\n"); printf("[2] cre 新建文件\n"); printf("[3] del 删除文件\n"); printf("[4] dis 显示文件内容\n"); printf("[5] fat 显示部分FAT及位示图\n"); printf("[6] exit 退出系统\n"); } // 功能:解释命令。根据不同的输入转到不同的函数执行 // str:键盘输入串 bool shell(char *str) { int re = -1, i = 0, cmdp = 0, filep = 0; char *p = str; char cmdstr[SHELL_LEN] = ""; char filestr[10] = ""; // 以下程序完成命令和参数的分解分别放到cmdstr,filestr数组中 while (*p == ' ') // 删除字符串前面空格 p++; int firstspace = 0; // 第一个空格 while (1) { if (*p == '\0') break; if (*p == ' ') { firstspace = 1; p++; } else { if (firstspace == 0) { cmdstr[cmdp++] = *p++; if (cmdp >= 5) { errorp(7); return false; } } else { filestr[filep++] = *p++; if (filep >= 4) { errorp(5); return false; } } } } filestr[filep] = '\0'; cmdstr[cmdp] = '\0'; for (i = 0; i < ShellCount; i++) if (strcmp(cmdstr, shellstr[i]) == 0) { re = i; break; } switch (re) { // 根据解释的命令执行对应的操作 case 0: direxc(filestr); break; case 1: if (strlen(filestr) == 0) { errorp(2); return false; } creexc(filestr); break; case 2: if (strlen(filestr) == 0) { errorp(2); return false; } delexc(filestr); break; case 3: if (strlen(filestr) == 0) { errorp(2); return false; } disexc(filestr); break; case 4: fatexc(); break; case 5: save(); exit(0); break; default: errorp(8); break; } return true; } int main() { char inputs[256] = ""; srand((unsigned)time(0)); // 每次产生不一样的随机数 init(); menu(); while (1) { printf("\n>"); gets(inputs); shell(inputs); menu(); } } 修改代码使之运行正确
06-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值