在C#的文件操作场景中,直接调用File.Delete方法删除文件会导致文件被永久移除,无法通过常规方式恢复,对于需要保留误删恢复能力的业务来说并不友好。实现回收站功能的核心思路是将待删除的文件移动到自定义的回收目录,同时记录文件的原始路径、删除时间等元数据,后续可以根据这些元数据将文件恢复到原来的位置,或者彻底清理回收站中的文件。

回收站功能的核心设计
完整的回收站功能需要包含以下几个核心模块:
- 回收目录初始化:创建用于存储软删除文件的目录,以及存储文件元数据的记录文件
- 软删除操作:将目标文件移动到回收目录,同时记录原始路径、删除时间等信息
- 文件恢复操作:根据元数据将回收目录中的文件移动回原始存储位置
- 彻底删除操作:永久删除回收目录中的指定文件,清理对应的元数据记录
- 回收站清理操作:批量清空回收站中的所有文件,清理所有元数据
基础配置与辅助类定义
首先定义回收站需要的配置信息和元数据模型,配置文件路径和回收目录路径,元数据模型用于存储软删除文件的相关信息。
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
namespace FileRecycleBinDemo
{
// 回收站配置类
public class RecycleBinConfig
{
// 回收目录存储路径,可根据实际需求调整
public string RecycleDirPath { get; set; } = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RecycleBin");
// 元数据文件路径,用于记录软删除文件的信息
public string MetaDataFilePath { get; set; } = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RecycleBin", "meta_data.json");
}
// 软删除文件元数据模型
public class DeletedFileMeta
{
// 唯一标识
public string Id { get; set; }
// 原始文件完整路径
public string OriginalPath { get; set; }
// 回收目录中的文件名称,避免文件名冲突
public string RecycleFileName { get; set; }
// 文件删除时间
public DateTime DeleteTime { get; set; }
// 原始文件大小(字节)
public long FileSize { get; set; }
}
}
回收站核心实现类
接下来实现回收站的核心操作类,包含初始化、软删除、恢复、彻底删除等方法。
public class RecycleBinManager
{
private readonly RecycleBinConfig _config;
private List<DeletedFileMeta> _metaList;
public RecycleBinManager(RecycleBinConfig config = null)
{
_config = config ?? new RecycleBinConfig();
InitRecycleBin();
LoadMetaData();
}
// 初始化回收站目录和元数据文件
private void InitRecycleBin()
{
if (!Directory.Exists(_config.RecycleDirPath))
{
Directory.CreateDirectory(_config.RecycleDirPath);
}
string metaDir = Path.GetDirectoryName(_config.MetaDataFilePath);
if (!Directory.Exists(metaDir))
{
Directory.CreateDirectory(metaDir);
}
if (!File.Exists(_config.MetaDataFilePath))
{
File.WriteAllText(_config.MetaDataFilePath, "[]");
}
}
// 加载元数据到内存
private void LoadMetaData()
{
string json = File.ReadAllText(_config.MetaDataFilePath);
_metaList = JsonSerializer.Deserialize<List<DeletedFileMeta>>(json) ?? new List<DeletedFileMeta>();
}
// 保存元数据到文件
private void SaveMetaData()
{
string json = JsonSerializer.Serialize(_metaList, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(_config.MetaDataFilePath, json);
}
// 软删除文件,将文件移动到回收站
public bool SoftDeleteFile(string filePath)
{
if (!File.Exists(filePath))
{
throw new FileNotFoundException("待删除文件不存在", filePath);
}
// 生成回收目录中的唯一文件名,避免重名冲突
string fileExt = Path.GetExtension(filePath);
string recycleFileName = $"{Guid.NewGuid()}{fileExt}";
string recycleFilePath = Path.Combine(_config.RecycleDirPath, recycleFileName);
// 移动文件到回收目录
File.Move(filePath, recycleFilePath);
// 记录元数据
FileInfo fileInfo = new FileInfo(recycleFilePath);
DeletedFileMeta meta = new DeletedFileMeta
{
Id = Guid.NewGuid().ToString(),
OriginalPath = Path.GetFullPath(filePath),
RecycleFileName = recycleFileName,
DeleteTime = DateTime.Now,
FileSize = fileInfo.Length
};
_metaList.Add(meta);
SaveMetaData();
return true;
}
// 恢复指定文件到原始路径
public bool RestoreFile(string metaId)
{
DeletedFileMeta meta = _metaList.Find(m => m.Id == metaId);
if (meta == null)
{
throw new ArgumentException("未找到对应的回收文件记录", nameof(metaId));
}
string recycleFilePath = Path.Combine(_config.RecycleDirPath, meta.RecycleFileName);
if (!File.Exists(recycleFilePath))
{
throw new FileNotFoundException("回收站中的文件已丢失", recycleFilePath);
}
// 确保原始路径的目录存在
string originalDir = Path.GetDirectoryName(meta.OriginalPath);
if (!Directory.Exists(originalDir))
{
Directory.CreateDirectory(originalDir);
}
// 如果原始路径已存在同名文件,先备份原文件
if (File.Exists(meta.OriginalPath))
{
string backupPath = meta.OriginalPath + ".bak";
File.Move(meta.OriginalPath, backupPath);
}
// 移动文件回原始路径
File.Move(recycleFilePath, meta.OriginalPath);
// 移除元数据记录
_metaList.Remove(meta);
SaveMetaData();
return true;
}
// 彻底删除回收站中的指定文件
public bool PermanentDelete(string metaId)
{
DeletedFileMeta meta = _metaList.Find(m => m.Id == metaId);
if (meta == null)
{
throw new ArgumentException("未找到对应的回收文件记录", nameof(metaId));
}
string recycleFilePath = Path.Combine(_config.RecycleDirPath, meta.RecycleFileName);
if (File.Exists(recycleFilePath))
{
File.Delete(recycleFilePath);
}
_metaList.Remove(meta);
SaveMetaData();
return true;
}
// 清空整个回收站
public void ClearRecycleBin()
{
// 删除回收目录中的所有文件
string[] files = Directory.GetFiles(_config.RecycleDirPath);
foreach (string file in files)
{
File.Delete(file);
}
// 清空元数据
_metaList.Clear();
SaveMetaData();
}
// 获取回收站中所有文件的信息
public List<DeletedFileMeta> GetAllDeletedFiles()
{
return _metaList;
}
}
使用示例
以下是回收站功能的具体使用示例,包含软删除、查询、恢复、彻底删除等操作。
class Program
{
static void Main(string[] args)
{
RecycleBinManager recycleBin = new RecycleBinManager();
// 测试软删除文件
string testFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.txt");
// 先创建测试文件
File.WriteAllText(testFilePath, "这是测试文件内容");
Console.WriteLine("开始软删除测试文件");
recycleBin.SoftDeleteFile(testFilePath);
Console.WriteLine("软删除完成,文件已移动到回收站");
// 查询回收站中的所有文件
List<DeletedFileMeta> deletedFiles = recycleBin.GetAllDeletedFiles();
Console.WriteLine($"回收站中共有{deletedFiles.Count}个文件");
foreach (var meta in deletedFiles)
{
Console.WriteLine($"文件ID:{meta.Id},原始路径:{meta.OriginalPath},删除时间:{meta.DeleteTime}");
}
// 恢复第一个文件
if (deletedFiles.Count > 0)
{
string firstMetaId = deletedFiles[0].Id;
Console.WriteLine($"开始恢复文件,ID:{firstMetaId}");
recycleBin.RestoreFile(firstMetaId);
Console.WriteLine("文件恢复完成");
Console.WriteLine($"原始路径文件是否存在:{File.Exists(testFilePath)}");
}
// 再次软删除测试文件
if (File.Exists(testFilePath))
{
recycleBin.SoftDeleteFile(testFilePath);
}
// 彻底删除回收站中的文件
deletedFiles = recycleBin.GetAllDeletedFiles();
if (deletedFiles.Count > 0)
{
string firstMetaId = deletedFiles[0].Id;
Console.WriteLine($"开始彻底删除文件,ID:{firstMetaId}");
recycleBin.PermanentDelete(firstMetaId);
Console.WriteLine("彻底删除完成");
}
// 清空回收站
// recycleBin.ClearRecycleBin();
// Console.WriteLine("回收站已清空");
}
}
注意事项
在实际使用过程中需要注意以下几点:
- 回收目录的权限问题,需要确保程序对回收目录有读写权限,避免文件移动失败
- 元数据文件需要做好备份,避免元数据丢失导致回收站中的文件无法恢复
- 如果软删除的是大文件,文件移动过程可能会有延迟,可以根据需求添加进度提示
- 恢复文件时需要校验原始路径的磁盘空间是否充足,避免恢复失败
- 多进程操作回收站时需要添加文件锁,避免元数据读写冲突
扩展思路
如果需要更完善的回收站功能,可以在现有基础上进行扩展:
- 添加回收站容量限制,超过容量时自动清理最早删除的文件
- 支持目录的软删除,递归处理目录下的所有文件并记录元数据
- 添加文件恢复前的冲突检测,提示用户处理同名文件
- 将元数据存储到数据库而不是本地文件,支持多端同步回收站状态