Пример #1
0
 /// <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;
 }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <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());
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
            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("无效路径");
                }
            }
Пример #7
0
            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("无效路径");
                }
            }
Пример #8
0
        /// <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);
        }
Пример #9
0
        /// <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);
        }
Пример #10
0
 /// <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;
 }
Пример #11
0
        /// <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;
        }
Пример #12
0
            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();
                }
            }
Пример #13
0
 /// <summary>
 /// 通过打开现有文件来初始化该类
 /// </summary>
 /// <param name="dir"></param>
 /// <param name="name"></param>
 private void OpenFile(INodeDirectory dir, String name)
 {
     inode = INode.Load(vfs, dir.Find(name));
 }
Пример #14
0
 /// <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);
 }
Пример #15
0
 /// <summary>
 /// 通过打开现有文件来初始化该类
 /// </summary>
 /// <param name="dir"></param>
 /// <param name="name"></param>
 private void OpenFile(INodeDirectory dir, String name)
 {
     inode = INode.Load(vfs, dir.Find(name));
 }
Пример #16
0
 /// <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);
 }