功能测试代码
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(); }
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; } } } }
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; } } }