public void DirectoryShoudBeDeleted() { var partition = new PartitionInfo {DeviceId = "D:"}; var type = BenchmarkType.Read; var size = 0x100; BenchmarkFile.OpenFileStream(partition, type, size, _ => { }); bool isExit = Directory.Exists(path); Assert.IsFalse(isExit); }
public static void OpenFileStream(PartitionInfo partition, BenchmarkType benchmarkType, int bufferSize, Action<FileStream> work) { OpenFileHandle(partition, benchmarkType, handle => { //打开文件流 using (FileStream stream = new FileStream(handle, FileAccess.Read, bufferSize, false)) { work(stream); } }); }
public void ReadShoudBeRead() { var partition = new PartitionInfo {DeviceId = "D:"}; var type = BenchmarkType.Read; var size = 0x100; BenchmarkFile.OpenFileStream(partition, type, size, stream => { Assert.IsTrue(stream.CanRead); Assert.IsFalse(stream.CanWrite); }); }
public override IOSpeed GetTestResult(PartitionInfo partition, BenchmarkType type, BenchmarkFlags flags, CancellationToken cancellationToken) { var randomBenchmarkTimes = new TimeSpan[this.outstandingThreadsCount]; BenchmarkFile.OpenFileHandle(partition, type, handle => { Parallel.For(0, this.outstandingThreadsCount, i => { using (FileStream stream = new FileStream(handle, FileAccess.Read, BlockSize)) { Action<byte[], int, int> work = Utility.GetReadOrWriteAction(type, stream); randomBenchmarkTimes[i] = DoBenchmarkAlgorithm(stream, work, flags, cancellationToken); } }); }); var totalTimes = randomBenchmarkTimes.Aggregate((a, b) => a + b); return new IOSpeed(time: totalTimes, ioCount: BlockCount, bytes: BlockCount * BlockSize); }
public static void OpenFileHandle(PartitionInfo partition, BenchmarkType benchmarkType, Action<SafeFileHandle> work) { FileAccess fileAccess = (benchmarkType.HasFlag(BenchmarkType.Read) ? FileAccess.Read : new FileAccess()) | (benchmarkType.HasFlag(BenchmarkType.Write) ? FileAccess.Write : new FileAccess()); string fullWorkDirectory = partition.DeviceId + workDirectory; string fileDirectory = $@"{fullWorkDirectory}\{fileName}"; DeleteDirectory(fullWorkDirectory); // 如果有,删除目录 Directory.CreateDirectory(fullWorkDirectory); // 创建测试目录 DecompressFolder(fullWorkDirectory); // 将测试目录的压缩选项取消 //打开文件句柄 using (SafeFileHandle handle = NativeMethods.CreateFile(fileDirectory, fileAccess, FileShare.None, IntPtr.Zero, FileMode.OpenOrCreate, FileFlags, IntPtr.Zero)) { int errorcode = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { //TODO: 本地化 throw new IOException($"测试临时文件创建失败。错误:{errorcode}", new Win32Exception(errorcode)); } work(handle); } DeleteDirectory(fullWorkDirectory); }
/// <summary> /// 将表示 Win32_LogicalDisk 的 WMI 对象转换为 PartitionInfo 对象。 /// </summary> /// <param name="logicalDiskObject">表示 Win32_LogicalDisk 的 WMI 对象。</param> /// <returns>转换后的 PartitionInfo 对象。</returns> public static PartitionInfo CreatePartitionInfoFromLogicalDiskObject(ManagementObject logicalDiskObject) { PartitionInfo partition = new PartitionInfo(); partition.Capacity = (long)(ulong)logicalDiskObject["Size"]; // 分区大小 partition.FreeSpace = (long)(ulong)logicalDiskObject["FreeSpace"]; // 剩余空间 partition.PartitionType = (int)(uint)logicalDiskObject["DriveType"]; // 磁盘类型 partition.FileSystem = (string)logicalDiskObject["FileSystem"]; // 文件系统 partition.DeviceId = (string)logicalDiskObject["DeviceID"]; // 盘符 partition.VolumeName = (string)logicalDiskObject["VolumeName"]; // 卷标 partition.SerialNumber = ((string)logicalDiskObject["VolumeSerialNumber"]).Trim(); // 分区序列号,头尾去除空格 // 获取卷对象用于获取分区的区块大小。 ManagementObject volumeObject = Utility.GetVolumeObjectByDeviceId(partition.DeviceId); // 如果获取到了就设置,如果没有获取到就设为 -1。 if (volumeObject != null) { partition.BlockSize = (long)(ulong)volumeObject["BlockSize"]; // 分区的区块大小。 } else { partition.BlockSize = -1; } ManagementObject diskPartitionObject = Utility.GetDiskPartitionObjectByDeviceId(partition.DeviceId); if (diskPartitionObject != null) // 此处同上。 { partition.Index = (int)(uint)diskPartitionObject["Index"]; // 分区的索引。 partition.StartingOffset = (long)(ulong)diskPartitionObject["StartingOffset"]; // 分区起始偏移。 } else { partition.StartingOffset = partition.Index = -1; // 如果无法获取,就设置其为 -1。 } return partition; }
/// <summary> /// 根据核心测试算法返回的时间计算结果。 /// </summary> /// <param name="partition">测试分区</param> /// <param name="arg">测试类型</param> /// <param name="flags">测试所需参数</param> /// <param name="cancellationToken">用以取消工作的取消标记</param> /// <returns></returns> public virtual IOSpeed GetTestResult(PartitionInfo partition, BenchmarkType type, BenchmarkFlags flags, CancellationToken cancellationToken) { TimeSpan result = new TimeSpan(); BenchmarkFile.OpenFileStream(partition, type, BlockSize, stream => { Action<byte[], int, int> work = GetReadOrWriteAction(type, stream); result = DoBenchmarkAlgorithm(stream, work, flags, cancellationToken); }); return new IOSpeed(time: result, ioCount: BlockCount, bytes: BlockCount * BlockSize); }