如何使用C#对虚拟磁盘文件(VHD)进行操作

功能测试代码

 VHDManager manager = new VHDManager("d:\\temp\\test.vhd");

                if (manager.IsSuccess())//如果初始化"Microsoft Virtual Hard Disk"成功
                {
                    //本地文件上传到虚拟磁盘
                    manager.UploadFile("d:\\temp\\face14.jpg", "文件上传测试.jpg");

                    //虚拟磁盘上的文件下载到本地
                    manager.DownloadFile("文件上传测试.jpg", "d:\\temp\\文件下载测试.jpg");

                    //列出虚拟磁盘上的文件
                    List<VHDFileInfo> list = manager.ListDir("");//根目录
                    if (list != null)
                    {
                        foreach (VHDFileInfo item in list)
                        {
                            Console.WriteLine(item.ToString());
                        }
                    }

                    manager.Close();
                }

封装代码,VHDManager.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using DiscUtils;
using DiscUtils.Partitions;
using DiscUtils.Ntfs;
using DiscUtils.Vhd;
using System.Diagnostics;

namespace testDiscUtils.VHDUtils
{
    /**
     * 标题: 如何使用C#对虚拟磁盘文件(VHD)进行操作
     * 功能: 新建虚拟磁盘(Microsoft Virtual File Disk),对虚拟磁盘上的文件/目录进行操作
     * 作者: Kagula
     * 日期: 2013-3-21
     * 环境: VS2010 SP1 C# , Framework 4.0 
     * 依赖:  DiscUtil 0.10(免费开源库)
     * 参考:  DiscUtil的官网       
     *        http://discutils.codeplex.com/     
     * 备注: [1]经测试可在虚拟磁盘(VHD)上直接使用带中文字符的文件名。
     * */
    class VHDManager
    {
        public int _diskSize = 30 * 1024 * 1024;//默认30M
        public String _label = "VHDUtils";//分区的默认标签

        bool _bSuccess = false;

        Stream _vhdStream;
        Disk _disk;
        NtfsFileSystem _ntfs;

        byte[] _buf512 = new byte[512];//(虚拟)磁盘读写缓存

        public bool IsSuccess()
        {
            return _bSuccess;
        }

        public VHDManager(String vhdFileName,bool bNoExistCreateNew=true)
        {
            if (File.Exists(vhdFileName) == false && bNoExistCreateNew==false)
            {
                return;
            }

            if (File.Exists(vhdFileName) == false && bNoExistCreateNew == true)
            {
                //如果不存在VHD(虚拟磁盘)文件,创建虚拟磁盘文件
                _vhdStream = File.Create(vhdFileName);

                _disk = DiscUtils.Vhd.Disk.InitializeDynamic(_vhdStream, Ownership.None, _diskSize);

                //创建NTFS(默认)分区
                BiosPartitionTable bpt = BiosPartitionTable.Initialize(
                    _disk, WellKnownPartitionType.WindowsNtfs);
                
                VolumeManager vm = new VolumeManager(_disk);
                LogicalVolumeInfo[] lvi = vm.GetLogicalVolumes();
                
                //格式化NTFS分区
                _ntfs = NtfsFileSystem.Format(lvi[0], _label);
            }
            else if (File.Exists(vhdFileName) == true)
            {
                Open(vhdFileName);
            }

            _bSuccess = true;
        }

        public void UploadFile(String localFN,String remoteFN)
        {
            //localFN
            if (File.Exists(localFN) == false)
            {
                Debug.WriteLine("警告:没有找到源文件!");
                return;
            }

            FileStream reader = new FileStream(localFN,FileMode.Open);

            //remoteFN
            if (_ntfs.FileExists(remoteFN))
            {
                Debug.WriteLine("警告:VHD上的["+remoteFN+"]文件将会被覆盖!");
                _ntfs.DeleteFile(remoteFN);
            }

            Stream stream = _ntfs.OpenFile(remoteFN, FileMode.Create);
            if (stream.CanWrite == false)
            {
                Debug.WriteLine("警告:无法写虚拟硬盘!");
                return;
            }

            int nReadDataLength = reader.Read(_buf512,0,_buf512.Length);

            while (nReadDataLength >0)
            {
                stream.Write(_buf512, 0, nReadDataLength); 
                nReadDataLength = reader.Read(_buf512, 0, _buf512.Length);
            }
            
            //关闭流
            stream.Flush();            
            stream.Close();
            reader.Close();
        }

        public void DownloadFile(String remoteFN, String localFN)
        {
            //localFN
            if (File.Exists(localFN) == true)
            {
                File.Delete(localFN);
                Debug.WriteLine("警告:目标文件已存在!");
            }

            FileStream writer = new FileStream(localFN, FileMode.CreateNew);

            //remoteFN
            if (_ntfs.FileExists(remoteFN)==false)
            {
                Debug.WriteLine("警告:VHD上的[" + remoteFN + "]源文件不存在!");
                return;
            }

            Stream stream = _ntfs.OpenFile(remoteFN, FileMode.Open);
            if (stream.CanRead == false)
            {
                Debug.WriteLine("警告:无法读虚拟硬盘!");
                return;
            }

            int nReadedBytes = stream.Read(_buf512, 0, _buf512.Length);

            while (nReadedBytes >0 )
            {
                writer.Write(_buf512, 0, nReadedBytes);
                nReadedBytes = stream.Read(_buf512, 0, _buf512.Length);                
            }

            //关闭流
            stream.Flush();
            stream.Close();
            writer.Close();
        }

        //删除虚拟磁盘上的文件
        public void DelRemoteFile(String remoteFile)
        {
            if (_ntfs.FileExists(remoteFile))
                _ntfs.DeleteFile(remoteFile);
        }

        //删除虚拟磁盘上的目录
        public void DelRemoteDir(String remoteDir)
        {
            if (!_bSuccess)
                return;

            if (_ntfs.DirectoryExists(remoteDir))
                _ntfs.DeleteDirectory(remoteDir);
        }

        //创建虚拟磁盘上的目录
        public void CreateRemoteDir(String remoteDir)
        {
            if (_ntfs.DirectoryExists(remoteDir))
                return;

            _ntfs.CreateDirectory(remoteDir);
        }

        //列出虚拟磁盘上指定文件夹下的文件和目录
        public List<VHDFileInfo> ListDir(String remoteDir)
        {
            List<VHDFileInfo> list = new List<VHDFileInfo>();

            String[] fileNames = _ntfs.GetFiles("");//根文件夹

            foreach (String fileName in fileNames)
            {
                DiscFileInfo dfi = _ntfs.GetFileInfo(fileName);

                VHDFileInfo fi = new VHDFileInfo();
                fi.Name = fileName;
                fi.Length = dfi.Length;
                fi.LastWriteTime = dfi.LastWriteTime;
                fi.isDir = false;

                list.Add(fi);
            }

            //第五步:列出指定目录下的目录
            String[] dicNames = _ntfs.GetDirectories("");//根文件夹

            foreach (String dicName in dicNames)
            {
                DiscDirectoryInfo ddi = _ntfs.GetDirectoryInfo(dicName);

                VHDFileInfo fi = new VHDFileInfo();
                fi.Name = dicName;
                fi.LastWriteTime = ddi.LastWriteTime;
                fi.isDir = true;

                list.Add(fi);
            }
            return list;
        }

        /**
         * 打开虚拟磁盘文件
         * */
        public bool Open(String vhdFileName)
        {
            //打开前先Close
            Close();

            //
            _disk = (DiscUtils.Vhd.Disk)Disk.OpenDisk(vhdFileName, FileAccess.ReadWrite);
            VolumeManager vm = new VolumeManager(_disk);

            SparseStream ss = vm.GetLogicalVolumes()[0].Open();

            //if(NtfsFileSystem.Detect(ss)) { is NTFS } else { is not NTFS }
            _ntfs = new NtfsFileSystem(ss);

            _bSuccess = true;

            return _bSuccess;
        }

        /**
         * 关闭虚拟磁盘
         * */
        public void Close()
        {
            if(_bSuccess)
            {
                if(_vhdStream!=null)
                    _vhdStream.Close();
                _bSuccess = false;
            }
        }
    }
}

封装代码,VHDFileInfo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testDiscUtils.VHDUtils
{
    public class VHDFileInfo:Object
    {
        public String Name;//文件名或目录名
        public long Length;//文件长度,字节为单位
        public bool isDir;
        public DateTime LastWriteTime;

        public override String ToString()
        {
            String s;

            s = String.Format("filename={0},length={1},LastWriteTime={2},isDir={3}", 
                Name, Length, LastWriteTime, isDir);

            return s;
        }
    }
}



你可能感兴趣的:(如何使用C#对虚拟磁盘文件(VHD)进行操作)