/// <summary> /// 创建一个新目录 /// </summary> /// <param name="vfs"></param> /// <returns></returns> public static INodeDirectory Create(VFSCore vfs) { INode inode = vfs.AllocateINode(1, 2333); INodeDirectory t = new INodeDirectory(vfs, inode); t.AddSelf(); return t; }
/// <summary> /// 根据 inode 建立 INodeDirectory /// </summary> /// <param name="vfs"></param> /// <param name="inode"></param> /// <returns></returns> public static INodeDirectory Load(VFSCore vfs, INode inode) { INodeDirectory t = new INodeDirectory(vfs, inode); t.Load(); return(t); }
/// <summary> /// 创建一个新目录 /// </summary> /// <param name="vfs"></param> /// <returns></returns> public static INodeDirectory Create(VFSCore vfs) { INode inode = vfs.AllocateINode(1, 2333); INodeDirectory t = new INodeDirectory(vfs, inode); t.AddSelf(); return(t); }
/// <summary> /// 格式化存储介质 /// </summary> /// <param name="inodeCapacity">inode 数量</param> /// <param name="blockSizeKByte">block 大小(KB),必须为 1,2,4,8 中的一个</param> public void Format(UInt32 inodeCapacity, UInt16 blockSizeKByte = 4) { if (inodeCapacity < 32) { throw new Exception("inode 至少为 32 个"); } if (!new int[] { 1, 2, 4, 8 }.Contains(blockSizeKByte)) { throw new Exception("block 大小只能为 1KB, 2KB, 4KB 或 8KB"); } uint offset = 0; offset += (uint)Utils.GetStructSize <_SuperBlock>(); offset += (inodeCapacity / 32 + 1) * 4; offset += (uint)Utils.GetStructSize <_INode>() * inodeCapacity; if (offset > deviceSize) { throw new Exception("inode 数量过大,结构超出存储介质最大空间"); } // 可留给数据块位图和数据块区的大小 uint sizeRemain = deviceSize - offset; // 全部留给数据块,可以有多少个数据块 uint blockCapacity = sizeRemain / blockSizeKByte >> 10; if (blockCapacity < 128) { throw new Exception("磁盘空间太小,至少要可以容纳 128 个块"); } // 删除 (blockCapacity / 32 + 1) * 4 大小的数据块,留作数据块位图使用 blockCapacity -= ((blockCapacity / 32 + 1) * 4 / blockSizeKByte) + 1; // 初始化 superBlock superBlock = SuperBlock.Create(this, inodeCapacity, (UInt16)(blockSizeKByte << 10), blockCapacity); // 单个 inode BitVector 可容纳 32 位 inodeBitmaps = new UInt32[inodeCapacity / 32 + 1]; device.WriteArray(superBlock.pInodeBitVectors, inodeBitmaps, 0, inodeBitmaps.Length); // 单个 block BitVector 可容纳 32 位 blockBitmaps = new UInt32[blockCapacity / 32 + 1]; device.WriteArray(superBlock.pBlockBitVectors, blockBitmaps, 0, blockBitmaps.Length); // 写入根目录 INodeDirectory.Create(this); Console.WriteLine("格式化成功。"); Console.WriteLine("SuperBlock: {0}", superBlock.ToString()); }
/// <summary> /// 删除一个目录项 /// </summary> /// <param name="name"></param> /// <returns></returns> public Boolean Delete(String name) { if (!Contains(name)) { return(false); } if (name == "." || name == "..") { return(false); } var inodeIndex = entries[name]; INode inode = INode.Load(vfs, inodeIndex); if (inode.IsDirectory()) { // 删除非空目录项:递归删除 INodeDirectory id = INodeDirectory.Load(vfs, inodeIndex); if (id.Size() > 2) { var l = id.List(); foreach (var pair in l) { id.Delete(pair.Key); } } } inode.data.linkCount--; if (inode.data.linkCount == 0) { inode.Resize(0); vfs.DeAllocateINode(inode.index); } else { inode.Save(); } entries.Remove(name); Save(); return(true); }
public Directory(VFSCore vfs, String path) { this.vfs = vfs; if (!path.EndsWith("/")) { path += "/"; } this.path = path; dir = INodeDirectory.Resolve(vfs, path); if (dir == null) { throw new Exception("无效路径"); } }
/// <summary> /// 添加一个目录目录项 /// </summary> /// <param name="name"></param> /// <param name="dir"></param> /// <returns></returns> public Boolean Add(String name, INodeDirectory dir) { if (Contains(name)) { return(false); } if (dir.Contains("..")) { return(false); } entries[name] = dir.inode.index; dir.inode.data.linkCount++; dir.inode.Save(); dir.AddParent(inode.index); Save(); return(true); }
/// <summary> /// 根据路径解析目录,路径必须以 / 结尾 /// </summary> /// <param name="path"></param> /// <returns></returns> public static INodeDirectory Resolve(VFSCore vfs, String path) { INodeDirectory root = Load(vfs, 0); var pathCom = path.Split('/'); var node = root; for (var i = 1; i < pathCom.Length - 1; ++i) { if (node.Contains(pathCom[i]) && INode.Load(vfs, node.Find(pathCom[i])).IsDirectory()) { node = Load(vfs, node.Find(pathCom[i])); } else { return(null); } } return(node); }
/// <summary> /// 根据 inode 建立 INodeDirectory /// </summary> /// <param name="vfs"></param> /// <param name="inode"></param> /// <returns></returns> public static INodeDirectory Load(VFSCore vfs, INode inode) { INodeDirectory t = new INodeDirectory(vfs, inode); t.Load(); return t; }
/// <summary> /// 添加一个目录目录项 /// </summary> /// <param name="name"></param> /// <param name="dir"></param> /// <returns></returns> public Boolean Add(String name, INodeDirectory dir) { if (Contains(name)) { return false; } if (dir.Contains("..")) { return false; } entries[name] = dir.inode.index; dir.inode.data.linkCount++; dir.inode.Save(); dir.AddParent(inode.index); Save(); return true; }
public File(VFSCore vfs, String path, FileMode fileMode) { this.vfs = vfs; var directory = VFS.GetPathDirectory(path); var name = VFS.GetPathName(path); VFS.AssertNameValid(name); INodeDirectory dir = INodeDirectory.Resolve(vfs, directory); if (dir == null) { throw new Exception("无法访问目录"); } switch (fileMode) { case FileMode.CreateNew: if (dir.Contains(name)) { throw new Exception("文件已存在"); } CreateFile(dir, name); break; case FileMode.Create: if (dir.Contains(name)) { OpenFile(dir, name); inode.Resize(0); } else { CreateFile(dir, name); } break; case FileMode.Open: if (!dir.Contains(name)) { throw new Exception("文件未找到"); } OpenFile(dir, name); break; case FileMode.OpenOrCreate: if (dir.Contains(name)) { OpenFile(dir, name); } else { CreateFile(dir, name); } break; case FileMode.Truncate: if (!dir.Contains(name)) { throw new Exception("文件未找到"); } OpenFile(dir, name); inode.Resize(0); break; case FileMode.Append: if (!dir.Contains(name)) { CreateFile(dir, name); } else { OpenFile(dir, name); position = inode.data.sizeByte; } break; default: throw new ArgumentException(); } }
/// <summary> /// 通过打开现有文件来初始化该类 /// </summary> /// <param name="dir"></param> /// <param name="name"></param> private void OpenFile(INodeDirectory dir, String name) { inode = INode.Load(vfs, dir.Find(name)); }
/// <summary> /// 通过创建一个新文件来初始化该类 /// </summary> /// <param name="vfs"></param> /// <param name="name"></param> /// <param name="dir"></param> private void CreateFile(INodeDirectory dir, String name) { inode = vfs.AllocateINode(0, 2333); dir.Add(name, inode); }