// 获取数据信息 private Types.VirtualDataInfo GetDataInfo(long pos) { Types.VirtualDataInfo res = new Types.VirtualDataInfo(); res.Position = pos; using (dpz3.File.BinaryFile file = new File.BinaryFile(workPath, System.IO.FileMode.OpenOrCreate)) { file.Position = pos * Data_Info_Size; // 读取Sign try { // 读取NextPosition res.NextPosition = file.Read(); res.NextPosition += file.Read() * 256; res.NextPosition += file.Read() * 256 * 256; res.NextPosition += file.Read() * 256 * 256 * 256; // 读取FirstChildPosition res.Length = file.Read(); res.Length += file.Read() * 256; } catch (Exception ex) { throw new Exception("磁盘数据损坏", ex); } } return(res); }
// 获取数据信息 private void ReadData(ref Types.VirtualDataInfo info) { using (dpz3.File.BinaryFile file = new File.BinaryFile(workPath, System.IO.FileMode.OpenOrCreate)) { file.Position = info.Position * Data_Info_Size + 6; // 读取Sign try { // 读取Data info.Data = file.Read(info.Length); } catch (Exception ex) { throw new Exception("磁盘数据损坏", ex); } } }
// 保存数据信息 private void SaveDataInfo(Types.VirtualDataInfo info) { using (dpz3.File.BinaryFile file = new File.BinaryFile(workPath, System.IO.FileMode.OpenOrCreate)) { file.Position = info.Position * Data_Info_Size; // 读取Sign try { // 输出NextPosition file.Write(GetBytesFromLong(info.NextPosition)); // 输出Length file.Write(GetBytesFromInt(info.Length)); } catch (Exception ex) { throw new Exception("磁盘数据损坏", ex); } } }
/// <summary> /// 保存文件 /// </summary> /// <param name="path"></param> /// <param name="bytes"></param> public void SaveFile(string path, byte[] bytes) { // 获取文件信息 var info = GetPathInfo(path); // 判断路径类型 if ((info.Type & Path_Type_Dir) == Path_Type_Dir) { throw new Exception($"\"{path}\"是文件夹"); } // 文件不存在,则创建 if (info.Type == 0) { CreateFile(path); info = GetPathInfo(path); } int idx = 0; var pos = info.FirstChildPosition; Types.VirtualDataInfo dInfo = new Types.VirtualDataInfo(); // 覆盖原有的数据段 while (pos > 0) { // 读取数据段 dInfo = GetDataInfo(pos); // 判断可写入长度 int len = bytes.Length - idx; if (len > Data_Size) { len = Data_Size; } // 拷贝数据 if (len > 0) { dInfo.Data = new byte[len]; Array.Copy(bytes, idx, dInfo.Data, 0, len); idx += len; } else { dInfo.Data = new byte[0]; } // 转移到下一个数据块 pos = dInfo.NextPosition; // 保存数据段 dInfo.Length = len; // 清理寻址在文件变小后可以降低文件的寻址数量,但是当文件忽大忽小时,会产生冗余存储块,不建议清理 //if (dInfo.Length < Data_Info_Size - 6) dInfo.NextPosition = 0; SaveData(dInfo); } // 循环添加数据段 while (idx < bytes.Length) { Types.VirtualDataInfo newInfo = new Types.VirtualDataInfo(); newInfo.NextPosition = 0; // 判断可写入长度 int len = bytes.Length - idx; if (len > Data_Size) { len = Data_Size; } // 拷贝数据 newInfo.Data = new byte[len]; Array.Copy(bytes, idx, newInfo.Data, 0, len); idx += len; // 数据区块增加 diskInfo.DataBlocks++; newInfo.Position = diskInfo.DataBlocks; newInfo.Length = len; // 保存磁盘信息 SaveDiskInfo(); // 保存数据段 SaveData(newInfo); // 向文件信息或上一个数据段增加 if (info.FirstChildPosition == 0) { info.FirstChildPosition = newInfo.Position; SavePathInfo(info); } else { dInfo.NextPosition = newInfo.Position; SaveDataInfo(dInfo); } // 将当前段填充为缓存段 dInfo = newInfo; } }