AUTHOR : KJ021320
BLOG : http://blog.youkuaiyun.com/kj021320/
TEAM : I.S.T.O
这几天都忙着写SHELL,为什么要写SHELL,对某种语言更深入的认识!例如IO SOCKET SYS DB 等都可以通过写SHELL来全面了解学习。
在.NET 1.1 中 没有包含获取 磁盘信息的类,估计当时候是为了兼容其他平台,呵呵!后来其他平台都不用.NET MS没办法!又为了加强.NET功能所以在
.NET2 以后都有直接获取磁盘信息的类了! 以上推理纯熟个人YY
OK 现在用
Reflector 打开反编译 .NET 核心类库!
然后找到DriveInfo
(感觉 JAVA这方面真的太那个了!哎!JAD 怎么都不如人家做得方便智能,而且操作起来很舒服)
找到
DriveFormat
现在来看看 .NET 内部是如何获取 磁盘的格式
//以下注释是我加入的
public string DriveFormat
{
get
{
//建立一个 磁盘卷标名字,以便让系统返回
StringBuilder volumeName = new StringBuilder(50);
// 获取系统文件格式名字
StringBuilder fileSystemName = new StringBuilder(50);
//设置错误模式
int newMode = Win32Native.SetErrorMode(1);
try
{
int num;
int num2;
int num3;
//核心语句! 调用WIN32API的 GetVolumeInformation
if (!Win32Native.GetVolumeInformation(this.Name, volumeName, 50, out num, out num2, out num3, fileSystemName, 50))
{
//判断有调用 有没有错误信息
int errorCode = Marshal.GetLastWin32Error();
if (errorCode == 13)
{
errorCode = 15;
}
__Error.WinIODriveError(this.Name, errorCode);
}
}
finally
{
Win32Native.SetErrorMode(newMode);
}
//然后返回 系统文件格式
return fileSystemName.ToString();
}
}
以上看得应该比较清晰了! 再看看 Win32Native一个内部类是如何声明WIN32API的
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
internal static extern bool GetVolumeInformation(string drive, StringBuilder volumeName, int volumeNameBufLen, out int volSerialNumber, out int maxFileNameLen, out int fileSystemFlags, StringBuilder fileSystemName, int fileSystemNameBufLen);
看了很简单了吧?
再看看 下面一个 获取 卷标的属性
还有一个SET的方法我就不贴出来了
public string VolumeLabel
{
get
{
StringBuilder volumeName = new StringBuilder(50);
StringBuilder fileSystemName = new StringBuilder(50);
int newMode = Win32Native.SetErrorMode(1);
try
{
int num;
int num2;
int num3;
if (!Win32Native.GetVolumeInformation(this.Name, volumeName, 50, out num, out num2, out num3, fileSystemName, 50))
{
int errorCode = Marshal.GetLastWin32Error();
if (errorCode == 13)
{
errorCode = 15;
}
__Error.WinIODriveError(this.Name, errorCode);
}
}
finally
{
Win32Native.SetErrorMode(newMode);
}
return volumeName.ToString();
}
}
看完这段代码 你会发现跟 获取磁盘的格式代码一样
只是返回不一样
现在接下来再看看他是如何获取 磁盘容量的
public long TotalSize
{
get
{
//获取磁盘总大小
long num2;
int newMode = Win32Native.SetErrorMode(1);
try
{
//这两个都是空余的空间
long num;
long num3;
if (!Win32Native.GetDiskFreeSpaceEx(this.Name, out num, out num2, out num3))
{
__Error.WinIODriveError(this.Name);
}
}
finally
{
Win32Native.SetErrorMode(newMode);
}
//返回磁盘大小
return num2;
}
}
以下是 WIN32API的定义
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
internal static extern bool GetDiskFreeSpaceEx(string drive, out long freeBytesForUser, out long totalBytes, out long freeBytes);
再来看看获取空余空间的方法
public long TotalFreeSpace
{
get
{
long num3;
int newMode = Win32Native.SetErrorMode(1);
try
{
long num;
long num2;
if (!Win32Native.GetDiskFreeSpaceEx(this.Name, out num, out num2, out num3))
{
__Error.WinIODriveError(this.Name);
}
}
finally
{
Win32Native.SetErrorMode(newMode);
}
return num3;
}
}
调用WIN32API都一样 只是返回不一样而已
再继续看下面的
public long AvailableFreeSpace
{
get
{
long num;
int newMode = Win32Native.SetErrorMode(1);
try
{
long num2;
long num3;
if (!Win32Native.GetDiskFreeSpaceEx(this.Name, out num, out num2, out num3))
{
__Error.WinIODriveError(this.Name);
}
}
finally
{
Win32Native.SetErrorMode(newMode);
}
return num;
}
}
看完之后无语了吧? 我个人感觉很SB每次获取都调用一下~ 就是把需要的返回 ,不需要的数据抛弃掉!
资源浪费啊! 为何不可以把对应的数据放到一个数组里面,下次调用的时候直接获取就可以了!
如果需要刷新看看磁盘状态有没有变化,那也可以提供一个 refresh的方法啊!