Board logo

标题: [已结]如何显示磁盘的剩余空间? [打印本页]

作者: namejm     时间: 2006-3-26 00:19    标题: [已结]如何显示磁盘的剩余空间?

操作系统为WinXP,想不借助第三方软件实现显示磁盘剩余空间的功能,潜水了好几天,写了如下代码,请大家帮帮我.
@echo off
rem                    存在问题
rem            
rem             1、怎样把字节数转换为以M为单位的数?
rem
rem             2、怎样才能不产生临时文件?
color 1f
title 显示C盘剩余空间
del size.txt>nul 2>nul
dir /-c c:\|find "可用字节">size.txt
for /f "tokens=3" %%a in (size.txt) do echo                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          C盘还有 %%a 字节剩余空间
del size.txt>nul 2>nul
echo.
echo.
echo.
echo                                      按任意键退出
pause>nul

  目前已经找到了完美的解决方案,请看代码:
@echo off
setlocal enabledelayedexpansion

:Main
cls
set /a num2=1024*1024
for %%i in (c d e f g h i j k l m n o p q r s t u v w x y z) do (
    if exist %%i:\ (
        set num3_str=
        set num4=
        for /f "tokens=3" %%j in ('dir /-c %%i:\') do set num1=%%j
            if not "!num1!"=="0" (
                call :loop
                for /f "delims=0 tokens=*" %%k in ("!num3_str!") do set num3_str=%%k
                echo.
                echo        %%i 盘剩余空间为 !num3_str! MB
                echo.
            )
        )
    )
)
pause
goto Main

:loop
:: 求商
set /a num3=%num4%%num1:~0,1%/%num2%
:: 求商序列
set num3_str=%num3_str%%num3%
:: 求余
set /a num4=%num4%%num1:~0,1%%%%num2%
if %num4% equ 0 set num4=
set num1=%num1:~1%
if not "%num1%"=="" goto loop
goto :eof
  出处:求所有分区剩余空间的精确值(以MB为单位)

[ Last edited by namejm on 2007-3-11 at 02:26 PM ]
作者: Climbing     时间: 2006-3-26 01:08
用:

set /a freesize=%%a/1048576

来计算MB,freesize成保存的就是MB为单位的数字了。

不产生临时文件的方法可能有点不雅观,试试这样:
for /f "tokens=3" %%a in ('dir /-c c:\') do set /a freesize=%%a/1048576

由于你需要的行在最后一行,虽然这样显得有点啰索,但确实能够满足需要。
作者: 3742668     时间: 2006-3-26 12:06
@echo off
echo 盘符        剩余空间        分区大小
wmic logicaldisk where caption="c:" get size,freespace,caption | findstr /v /i "caption"
pause>nul
作者: Climbing     时间: 2006-3-26 14:27
wmic是什么东东?
作者: namejm     时间: 2006-3-26 15:56


  Quote:
Originally posted by Climbing at 2006-3-26 01:08:
用:

set /a freesize=%%a/1048576

来计算MB,freesize成保存的就是MB为单位的数字了。

不产生临时文件的方法可能有点不雅观,试试这样:
for /f "to ...

试了一下,提示说找不到操作数,不知何故.
作者: willsort     时间: 2006-3-26 20:12
Re Climbing:

  Quote:
WMI 命令行WMI 命令行提供了到 Windows 管理规范 (WMI) 的简单命令行接口。WMIC 提供了到 WMI 的简单接口,这样即可利用 WMI 管理运行 Microsoft Windows 的计算机。WMIC 与现有命令行程序和实用程序命令相互操作,且很容易通过脚本或其它面向管理的应用程序来扩展 WMIC。

WMIC 允许以下操作:

通常使用使 WMI 更直观的“别名”,浏览 WMI 模式并查询它们的类和实例。
以单一命令方式使用本地计算机、远程计算机或多台计算机。
自定义别名并输出符合需要的格式。
创建和执行基于 WMIC 的脚本。

WMI 提供程序允许 WMI 管理大量的硬件组件、操作系统子系统和应用程序系统。WMIC 可与由这些 WMI 提供程序执行的所有模式一起使用。

可以在任何启用了 WMIC 的计算机上,使用 WMIC 远程管理任何具有 WMI 的计算机。对 WMIC 而言,不必为了管理远程管理的计算机而使其在该远程管理的计算机上可用。

方案
下列典型方案,使用 WMIC 使任务执行容易:
本地管理计算机—使用 WMIC 命令管理本地计算机。
远程管理计算机—使用 WMIC 管理其它计算机。
远程管理多台计算机—在一台计算机上通过 WMIC 使用单一命令管理多台计算机。
远程管理计算机(使用远程会话)—使用远程会话技术(如 Telnet 或终端服务)连接到远程计算机并使用 WMIC 对其进行管理。
使用管理脚本进行自动管理—使用 WMIC 编写简单的管理脚本,自动化管理计算机(本地、远程或多台计算机—顺序进行或同时进行)。
别名
通过称为“别名”的中间援助器使用 WMIC 时,可访问 WMI 结构。别名用来捕捉和一些特定的任务(比如磁盘或网络管理)相关联的 WMI 等级的特征。别名可用于为 WMI 类别、属性和方法提供更好的名称,或者以有用的输出格式排列属性。输出格式可以包括具体的属性值,或者以对某个具体表示法策略或功能适当的方式进行格式化。例如,别名可能具有“BRIEF”格式,此格式仅列出可通过别名来鉴定可视化对象的基本属性值。以 XML 格式检索管理数据,而且该数据通过内置或自定义 XSL 输出格式进行处理。

请参阅

WMI 概述
调用 WMIC
使用 WMIC
扩展别名
参考
用 WMIC 管理系统
Windows 管理规范命令行 (WMIC) 工具

以上引自XP帮助与支持中心文档
ms-its:C:\WINDOWS\Help\WMIC.chm::/WMIC_Overview.htm

Re namejm:

      需要使用find过滤掉非文件大小的文本行

for /f "tokens=3" %%a in ('dir /-c c:\^|find "可用字节"') do set /a freesize=%%a/1048576
作者: Climbing     时间: 2006-3-26 20:34
嗯,受教了。
作者: namejm     时间: 2006-3-27 02:08
to willsort:
需要使用find过滤掉非文件大小的文本行

for /f "tokens=3" %%a in ('dir /-c c:\^|find "可用字节"') do set /a freesize=%%a/1048576

试运行了这段代码,用echo %freesize%来显示结果,结果居然显示负数,让人大跌眼镜.比如,我的C盘大小为2305712128字节,结果显示的是-1897.难道CMD神经错乱了不成?
作者: willsort     时间: 2006-3-27 09:14
Re namejm:

      CMD没有神经错乱,是set处理的整数太大了,set使用双字节存储整数,有32位的存贮范围限制,也就是说它的处理范围是2^-31~2^31-1,你的磁盘空间超过了这个范围溢出了。

      对此我没有太好的解决办法,只有舍弃后三位后除以1049的近似算法。

for /f "tokens=3" %%a in ('dir /-c c:\^|find "可用字节"') do set freesize=%%a
set /a freesize=%freesize:~0,-3%/1049>nul
echo Freesize:%freesize%
作者: namejm     时间: 2006-3-27 17:58
谢谢版主的详细解答.看来只能用个差不多的数字了.
作者: bagpipe     时间: 2006-3-29 11:12
for /f "tokens=3" %%a in ('dir /-c c:\^|find "可用字节"') do set freesize=%%a这句我执行不了,不知道为什么加个^前导字符,请各位试验下,我的是2000,没有执行成功,所以改用其他方法得到结果.........
作者: 3742668     时间: 2006-3-29 11:24
XP,SP2正常。
试试for /f "tokens=3" %%a in ('"dir /-c c:\ | find "可用字节""') do set freesize=%%a
用^来转义,否则执行的是 dir /-c c:\ find "可用字节"
作者: MIN     时间: 2006-3-29 11:41
DOS下能不能检测磁盘剩余空间呢?
作者: namejm     时间: 2006-4-13 23:01
如果想查询所有存在的磁盘分区的剩余空间大小,用下面的方法为什么得不到正确结果呢
for %%a in (c d e f g h i j k l m n o p q r s t u v w x y z) do @(
if exist %%a:\recycler\nul (
for /f "tokens=3" %%b in ('dir /-c %%a:\^|find "可用字节"') do set freesize=%%b
set /a freesize=%freesize:~0,-3%/1049>nul
echo %% a 盘剩余空间:%freesize% MB
)

[ Last edited by namejm on 2006-4-14 at 12:59 ]
作者: DOSforever     时间: 2006-4-14 00:13


  Quote:
Originally posted by MIN at 2006-3-29 11:41:
DOS下能不能检测磁盘剩余空间呢?

能。见:如何检测分区的剩余空间
作者: namejm     时间: 2006-4-14 13:02


  Quote:
Originally posted by bagpipe at 2006-3-29 11:12:
for /f "tokens=3" %%a in ('dir /-c c:\^|find "可用字节"') do set freesize=%%a这句我执行不了,不知道为什么加个^前导字符,请各位试验下,我的是2000,没有执行成功,所以改用其他方法得到结果.........

能不能说一下你用什么方法实现的,我正好需要在2000下测试个批处理.谢谢.

[ Last edited by namejm on 2006-4-15 at 14:31 ]
作者: smileseeker     时间: 2006-4-14 17:15
for /f "tokens=3" %%a in ('"dir /-c c:\ | find "可用字节""') do set freesize=%%a



这个 方法很好啊
作者: chenhui530     时间: 2006-4-15 21:41
直接调用VBS应该简单的多
作者: 3742668     时间: 2006-4-17 01:00
其实应该是bat比vbs简单得多。
作者: namejm     时间: 2006-4-17 18:17


  Quote:
Originally posted by 3742668 at 2006-4-17 01:00:
其实应该是bat比vbs简单得多。

那如果想查询所有存在的磁盘分区的剩余空间大小,要求用MB为单位,不借助第三方软件,该如何写代码呢?
在2000下能实现这个功能吗?
作者: namejm     时间: 2006-4-21 19:43
在XP环境下,想查询每个分区的剩余空间,以MB为单位显示,以下代码为什么不能得出正确结果呢?
for %%a in (c d e f g h i j k l m n o p q r s t u v w x y z) do @(
if exist %%a:\nul (
for /f "tokens=3" %%b in ('dir /-c %%a:\^|find "可用字节"') do set freesize=%%b
set /a freesize=%freesize:~0,-3%/1049>nul
echo %% a 盘剩余空间:%freesize% MB
)
作者: 3742668     时间: 2006-4-21 22:44
估计是因为你没有启用延迟环境变量的缘故,导致freesize的值以为未变。建议用SETLOCAL ENABLEDELAYEDEXPANSION来启用延迟环境变量,另外需用!freesize!来替代%freesize%。不过既然是XP,何必考虑一个命令搞定呢?
@echo off
for /f "tokens=1,2" %%i in ('"wmic logicaldisk get freespace,caption"') do set %%i=%%j
echo C盘剩余空间为:  %c:% 字节
echo D盘剩余空间为:  %d:% 字节
echo E盘剩余空间为:  %e:% 字节
pause

作者: namejm     时间: 2006-4-22 13:03


  Quote:
Originally posted by 3742668 at 2006-4-21 22:44:
估计是因为你没有启用延迟环境变量的缘故,导致freesize的值以为未变。建议用SETLOCAL ENABLEDELAYEDEXPANSION来启用延迟环境变量,另外需用!freesize!来替代% ...

因为想显示所有存在的分区的剩余空间,并且要以MB为单位显示,所以要用到for语句,对SETLOCAL ENABLEDELAYEDEXPANSION的使用不是很了解,具体要修改什么地方,能不能在我贴出来的代码基础上进行修改呢?谢谢.
作者: 3742668     时间: 2006-4-22 13:32
刚才看了一下,你的代码明显差个),所以首先应该在最后加个)
其次,echo %% a 中间多了个空格。
再次,算法有问题,结果可能出现错误。
最后,SETLOCAL ENABLEDELAYEDEXPANSION的用法:
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for %%a in (c d e f g h i j k l m n o p q r s t u v w x y z) do (
if exist %%a:\nul (
for /f "tokens=3" %%b in ('dir /-c %%a:\^|find "可用字节"') do set freesize=%%b
set /a freesize=!freesize:~0,-3!/1049>nul
echo %%a 盘剩余空间:!freesize! MB
)
)
pause
如果想得到精确的以mb为单位的空间数也不是没有办法,只要把除法改成减法自己写代码分两部分算就行了,当然,没什么实用性。
其实利用wmic可以保存各个盘的剩余空间数,然后自己再通过运算来获得mb数应该简单一些。
作者: chineselgs     时间: 2006-4-22 13:44
看不太懂~~~~~~~~~~
作者: namejm     时间: 2006-4-22 17:16
to 3742668:
感谢你的耐心回答,解决了一个困扰我很久的难题,再次感谢.

"如果想得到精确的以mb为单位的空间数也不是没有办法,只要把除法改成减法自己写代码分两部分算就行了"
----呵呵,想不到还有这样的写法,批处理真是太有趣了,能不能贴段代码出来开开眼界呢?

"当然,没什么实用性。"
----你是说分成两段代码的做法没实用性还是说以MB为单位显示没实用性呢?如果是后者的话,我可不太同意你的说法.

"其实利用wmic可以保存各个盘的剩余空间数,然后自己再通过运算来获得mb数应该简单一些。"
----这样做会产生临时文件吗?如果要产生临时文件的话,感觉还不是很完美.

[ Last edited by namejm on 2006-4-22 at 17:42 ]
作者: 3742668     时间: 2006-4-22 18:40
1.算起来比较麻烦,把思路说一下你自己尝试了看吧:
其实就是按照手算除法一样,不过分成两部分,先用前7位与1048576计算,然后把减剩下的加前7位以外的组合了再与1048576计算,最后把两部分的结果合并起来就行了。
2,之所以说没有什么实用性,因为考虑到执行速度以及繁琐程度,不如改用其它的方法。
3,我想你没有仔细去看那个wmic结果的批处理,你仔细再看看结果是保存在变量中还是保存在文件中。。
作者: namejm     时间: 2006-4-22 22:34


  Quote:
Originally posted by 3742668 at 2006-4-22 18:40:
3,我想你没有仔细去看那个wmic结果的批处理,你仔细再看看结果是保存在变量中还是保存在文件中。。

呵呵,不是我没看,是我对wmic很陌生,看不懂:(
还是谢谢你的解答.
作者: namejm     时间: 2006-4-22 22:47
在2000系统环境中,for /f "tokens=3" %%b in ('dir /-c %%a:\^|find "可用字节"') do set freesize=%%b这句始终不能得到正确结果,请问该如何修改代码?
作者: namejm     时间: 2006-6-11 18:29
  29楼的问题有人解答吗?很想知道该怎么处理。
作者: willsort     时间: 2006-6-11 18:54
Re namejm:

      可惜没有Win2000的环境,无法测试,对症的解法需要你详细说明错误信息。

      目前,我能想到的办法就是取消find,在CMD@WinXP下测试有效:
@echo off & setlocal EnableDelayedExpansion
for %%d in (c d e f g h i j k l m n o p q r s t u v w x y z) do (
    if exist %%d:\nul (
        for /f "tokens=3" %%z in ('dir /-c %%d:\') do set freesize=%%z
        set /a freesize=!freesize:~0,-3!/1049>nul
        set freesize=         !freesize!
        set freesize=!freesize:~-9!
        echo %%d 盘剩余空间:!freesize! MB
    )
)
pause

作者: namejm     时间: 2006-6-11 20:08    标题: 通过截取字符的方法排版出现错误

  通过截取字符最后几位的方法右对齐显示磁盘卷标名和剩余空间的时候,发生了如下的错误格式(当卷标名全为英文的时候能正确排版),请问是何原因?
  代码和图片如下
@echo off
cls
color 2e
title 各分区剩余空间情况
echo.
echo.
echo        ╔══════════════════════════════╗
echo        ║        磁盘分区         磁盘卷标名      剩余空间(MB)       ║
echo        ║    _____________________________________________________   ║
setlocal enabledelayedexpansion
for %%a in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
  if exist %%a:\nul (
    for /f "tokens=3" %%b in ('dir /-c %%a:\^|find "可用字节"') do (
      set freesize=%%b
      set /a freesize=!freesize:~0,-3!/1049>nul 2>nul
      set freesize=       !freesize!
      set freesize=!freesize:~-7!
      for /f "tokens=4" %%c in ('vol %%a:')  do set volume=%%c
      set volume=                    !volume!
      set volume=!volume:~-20!
      echo        ║           %%a: !volume!        !freesize!           ║
    )
  )
)
echo        ╚══════════════════════════════╝
pause>nul
  

[ Last edited by willsort on 2006-6-12 at 19:31 ]
附件 1: error1.jpg (2006-6-11 20:08, 37.38 K, 下载附件所需积分 1点 ,下载次数: 2)



作者: willsort     时间: 2006-6-11 20:23
Re namejm:

      因为NT内部采用Unicode编码,而Unicode字符有一个特点——“不同显示宽度的英文和中文字符,有相同的字节长度和字符长度”。

      这个问题解决起来比较困难。替代的方案无非就是保证不出现中文(也即不显示卷标),或者依照我原来的建议不使用边框并将卷标列移到后方。
作者: namejm     时间: 2006-6-11 21:03
  真是鱼和熊掌不可兼得啊:(
作者: willsort     时间: 2006-6-12 19:27
Re namejm:

      现在,想到一些方案来对齐汉字或其它多字节字符了。

      如果可以确保显示的变量串只有汉字,则补齐变量时可以用空白的汉字(比如全角状态下的空格)来代替普通的空格;

      否则,需要判断变量串的显示宽度,在缺省的中文环境下,可以理解为判断本地编码(ANSI)的变量串的字节长度,关于此点,现在的方案是生成临时文件(缺省采用ANSI编码),根据文件长度确定变量长度。代码如下[1]

      但是,它仍然无法对NTFS超长的卷标进行对齐。所以我仍然建议,不要强求去采用某些特殊的字符排列方式。可以代替的方案有很多,比如,卷标可以写在前面,而盘符将加上一对圆括弧紧跟在卷标后,如我的电脑中显示的那样。

     而在边框中显示变化字符串,将始终潜伏着边框不对齐的隐患,而且它也影响了代码本身的阅读性,而不使用边框用其它方法也可以取得良好的排版效果。

     另外,图片附件体积过大,只留一个就以示意;另外,CMD窗口的截图采用16的GIF体积会小很多,效果也不会太失真。

[1]DrvSpace.cmd
@echo off & setlocal EnableDelayedExpansion
color 2e
title 各分区剩余空间情况
echo.
echo.
echo        ╔══════════════════════════════╗
echo        ║        磁盘分区         磁盘卷标名      剩余空间(MB)       ║
echo        ║    _____________________________________________________   ║
for %%d in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
    if exist %%d:\nul (
        for /f "tokens=3" %%z in ('dir /-c %%d:\') do set freesize=%%z
        set /a freesize=!freesize:~0,-3!/1049>nul
        set freesize=         !freesize!
        set freesize=!freesize:~-9!
        for /f "tokens=3*" %%v in ('vol %%d:') do set volume=%%w
        echo.!volume!>_volume.tmp
        for %%f in (_volume.tmp) do for /l %%v in (%%~zf,1,20) do set volume= !volume!
echo        ║           %%d:   !volume!     !freesize!           ║
    )
)
echo        ╚══════════════════════════════╝
if exist _volume.tmp del _volume.tmp
pause
[ Last edited by willsort on 2006-6-12 at 19:34 ]
作者: namejm     时间: 2006-6-12 23:13
  感谢willsort,已经将代码稍加修改放进我的文件备份器脚本中去了。尽管还有潜在的风险,但是发出来之后,就会有更多的人来想办法,总比什么也不做强一点。

  刚发了几张图片,没注意到图片格式和颜色质量对图片大小的影响,以后我会注意发那些尽可能小而又比较清晰的图片上来。
作者: willsort     时间: 2006-6-14 16:51

───────────────── 版务记录 ─────────────────
执行:Will Sort
操作:合并主题 {21183}通过截取字符的方法排版出现错误 -> 32~36 楼
说明:操作主题与本主题存在上下文的直接联系
───────────────── 版务记录 ─────────────────

作者: mobo     时间: 2006-9-19 08:41    标题: 查看logicaldisk[逻辑盘]摘要信息

::查看logicaldisk[逻辑盘]摘要信息.bat:
::---------BY MOBO in 2006-09-18
wmic logicaldisk list brief /format:hform >logicaldisk.htm
作者: electronixtar     时间: 2006-9-19 08:56
寒~~现在动不动都WMIC的~~
作者: namejm     时间: 2006-9-19 09:40


  Quote:
Originally posted by electronixtar at 2006-9-19 08:56:
寒~~现在动不动都WMIC的~~

  呵呵,看来electronixtar对WMIC比较了解,想请教一下WMIC和CMD各有什么优劣。
作者: electronixtar     时间: 2006-9-19 10:03
cmd亲近bat而wmic亲近wbem,没了~~

其实了解也不多~~听说过而已~~BagPipe是专家,不过又不发帖~~

其实Windows越来越有UNIX的味道了~~

[ Last edited by electronixtar on 2006-9-19 at 10:07 ]
作者: zouzhxi     时间: 2006-9-22 07:56


  Quote:
Originally posted by willsort at 2006-6-11 18:54:
Re namejm:

      可惜没有Win2000的环境,无法测试,对症的解法需要你详细说明错误信息。

      目前,我能想到的办法就是取消find,在CMD@WinXP下测试栮..

如果是要显示硬盘总大小呢   怎么写....
作者: HUNRYBECKY     时间: 2007-1-21 10:26
如果DOS支持浮点运算的话,那么获取磁盘空间还可以使用如下方法:
for /f "skip=4 tokens=4 delims=, " %%a in ('defrag c: -a') do (set /a freesize=%%a*1024)
pause
可惜的是提示错误,原因是不支持浮点运算。
作者: HUNRYBECKY     时间: 2007-1-21 10:43
刚才研究了下,修改了上面的代码就可以实现变相的浮点预算了。
for /f "skip=4 tokens=4 delims=, " %%a in ('defrag d: -a') do echo %%a>ok.txt
for /f "tokens=1* delims=." %%a in (ok.txt) do set /a ok=%%a*1024+%%b*1024/100
echo %OK%
pause

作者: HUNRYBECKY     时间: 2007-1-21 10:47
在修改下,发现FOR命令居然支持调用变量作为SET集,这下不用产生临时文件了。
@echo off
set /p mydisk=请你输入要查询的磁盘(如E:):
for /f "skip=4 tokens=4 delims=, " %%a in ('defrag %mydisk% -a') do set dftemp=%%a
for /f "tokens=1* delims=." %%a in ("%dftemp%") do set /a diskfree=%%a*1024+%%b*1024/100
echo %mydisk%的剩余空间为:%diskfree%MB
pause
不好意思,对FOR不是很熟悉,一直用不好

[ Last edited by HUNRYBECKY on 2007-1-21 at 11:06 AM ]
作者: qiongshuai     时间: 2007-3-2 06:11
似乎很好的东西啊,谢谢了我还是新手阿
作者: kongsub     时间: 2007-10-22 00:06
2003下新出了个命令 freedisk 对应文件 freedisk.EXE