回 帖 发 新 帖 刷新版面

主题:[原创]一个老问题:搜索文件(包含子目录名)

'这个问题我在论坛发过帖子
'现在这个帖子找不到了
'这是重新优化过的过程
'CALL absolute 过程是由QB45提供的
'这个过程能够搜索到当前路径下的所有文件名及子目录名(不管文件什么属性)
'如果在根目录,也能够获得分区的卷标名

DEFINT A-Z
FUNCTION Dirs$ (Path AS STRING, Attr AS INTEGER, Size as LONG)
'******************************************************
'  搜索目录下的所有文件和文件夹,适用7.1和4.5版本
'  Attr位 8=卷标 16=目录 其他为文件
'  第一次调用时Path为要搜索的路径,第二次调用时Path请置空
'  返回:Attr=文件属性  Size=文件长度
'******************************************************
STATIC Lc AS INTEGER
STATIC ErrCode AS INTEGER
STATIC FileDATA AS STRING * 44
STATIC FirstCode AS STRING * 28
STATIC NextCode AS STRING * 18
STATIC FileName AS STRING * 64
IF Lc = 0 THEN
      Lc = 1
      DIM AsmCode AS STRING * 12
      '=================================================================
      MID$(AsmCode, 1, 3) = CHR$(&H68) + MKI$(VARSEG(FileDATA))
      MID$(AsmCode, 4, 1) = CHR$(&H1F)
      MID$(AsmCode, 5, 3) = CHR$(&HBA) + MKI$(VARPTR(FileDATA))
      MID$(AsmCode, 8, 2) = CHR$(&HB4) + CHR$(&H1A)
      MID$(AsmCode, 10, 2) = CHR$(&HCD) + CHR$(&H21)
      MID$(AsmCode, 12, 1) = CHR$(&HCB)
      '=================================================================
   
      DEF SEG = VARSEG(AsmCode): CALL ABSOLUTE(VARPTR(AsmCode)): DEF SEG
      '=================================================================
      MID$(FirstCode, 4, 1) = CHR$(&H1F)
      MID$(FirstCode, 8, 3) = CHR$(&HB8) + CHR$(&H0) + CHR$(&H4E)
      MID$(FirstCode, 11, 3) = CHR$(&HB9) + MKI$(255)
      MID$(FirstCode, 14, 2) = CHR$(&HCD) + CHR$(&H21)
      MID$(FirstCode, 16, 3) = CHR$(&H68) + MKI$(VARSEG(ErrCode))
      MID$(FirstCode, 19, 1) = CHR$(&H1F)
      MID$(FirstCode, 20, 2) = CHR$(&H72) + CHR$(&H2)
      MID$(FirstCode, 22, 2) = CHR$(&H33) + CHR$(&HC0)
      MID$(FirstCode, 24, 1) = CHR$(&H3E)
      MID$(FirstCode, 25, 3) = CHR$(&HA3) + MKI$(VARPTR(ErrCode))
      MID$(FirstCode, 28, 1) = CHR$(&HCB)
      
      '=================================================================
      MID$(NextCode, 1, 3) = CHR$(&HB8) + CHR$(&H0) + CHR$(&H4F)
      MID$(NextCode, 4, 2) = CHR$(&HCD) + CHR$(&H21)
      MID$(NextCode, 6, 3) = CHR$(&H68) + MKI$(VARSEG(ErrCode))
      MID$(NextCode, 9, 1) = CHR$(&H1F)
      MID$(NextCode, 10, 2) = CHR$(&H72) + CHR$(&H2)
      MID$(NextCode, 12, 2) = CHR$(&H33) + CHR$(&HC0)
      MID$(NextCode, 14, 1) = CHR$(&H3E)
      MID$(NextCode, 15, 3) = CHR$(&HA3) + MKI$(VARPTR(ErrCode))
      MID$(NextCode, 18, 1) = CHR$(&HCB)
      '=================================================================
END IF

IF Path$ <> "" THEN
      FileName = Path + CHR$(0)

      MID$(FirstCode, 1, 3) = CHR$(&H68) + MKI$(VARSEG(FileName))
      MID$(FirstCode, 5, 3) = CHR$(&HBA) + MKI$(VARPTR(FileName))

      DEF SEG = VARSEG(FirstCode)
      CALL ABSOLUTE(VARPTR(FirstCode)): DEF SEG

      IF ErrCode THEN EXIT FUNCTION
ELSE

      DEF SEG = VARSEG(NextCode)
      CALL ABSOLUTE(VARPTR(NextCode)): DEF SEG

      IF ErrCode THEN EXIT FUNCTION
END IF

File$ = MID$(FileDATA, 31)
Dirs$ = LEFT$(File$, INSTR(File$, CHR$(0)) - 1)
Attr% = ASC(MID$(FileDATA, 22, 1))
Size& = CVL(MID$(FileDATA, 27, 4))
END FUNCTION

回复列表 (共16个回复)

沙发

谢谢

板凳

:: 还有批处理的。。。


:: Visit.bat - 文件遍历批处理程序
:: Will Sort - 10/17/2004 - V2
::
:: 程序用途:
::     对指定文件集/目录集/文件列表执行指定操作
::
:: 命令行说明:
::     1. VISIT 文件集/目录集 [参数]
::        对文件集/目录集执行指定操作
::     2. VISIT @ 文件列表
::        对指定文件列表中的文件执行指定操作
::        
:: 注意事项:
::     - 文件集/目录集 中可包含有效路径和通配符
::     - 路径缺省为当前路径,文件集缺省为 *.* (并非所有文件)  
::     - 文件集/目录集 含空格时需用双引号引起
::     - [参数] 支持的DIR开关: /S /A /O /L等不与 /B 冲突者
::     - [参数] 不支持的DIR开关: /W /P /V 等与 /B 冲突者
::     - [操作] 由调用者预先写入 visitcmd.bat 中
::     - [操作] 中使用 %VisitFile% 引用遍历文件
::     - 程序检查检查 [文件列表] 是否存在,但不检查它是否有效
::     - 不遍历隐藏/系统目录下的目录和文件(在命令行中指定时例外)
::
:: 用法示例:
::     visit c:\ /ad /s             遍历C盘所有目录,包含子目录
::     visit "C:\My document" /a-d  遍历"C:\My document"下所有文件
::     visit C:\*.zip /a /s         遍历C盘所有.zip压缩包,包含子目录
::     如想遍历多个文件/目录集,可多次使用"DIR 文件集 /a /s>>文件列表"
:: 生成一个完整的文件列表,再使用文件列表进行遍历;或者使用VisitCE.Bat
::     在遍历未显式指定的隐藏/系统目录时,可以用"attrib 文件集 /s"生成
:: 文件列表,然后在visitcmd.bat的代码中引用%VisitFile%第三至最后的串,
:: 再使用文件列表进行遍历
::
:: 测试报告:
::     在 Win98 命令行方式下有限黑箱测试通过
::     性能仍然是最大的瓶颈
::          
@echo off
if "%1"=="@" goto CopyList

:MakeList
dir /b %1 %2 %3 %4 %5 %6 > ~visit.lst
find "~visit.lst" /v < ~visit.lst > ~visit.tmp
if not errorlevel 1 copy ~visit.tmp ~visit.lst>nul
goto MakePreLine

:CopyList
if not [%2]==[] if exist %2 copy %2 ~visit.lst>nul
if not exist ~visit.lst goto End

:MakePreLine
echo set VisitFile=> ~visit.pre
for %%c in (rcx e w q) do echo %%c>> ~visit.asd
debug ~visit.pre < ~visit.asd > nul
if [%OS%]==[Windows_NT] chcp 936 > nul

:LoopVisit
copy ~visit.pre+~visit.lst ~visit.tmp > nul
find "set VisitFile=" < ~visit.tmp > ~visit.bat
call ~visit.bat
if "%VisitFile%"=="" goto Clear
if not exist visitcmd.bat echo Visiting %VisitFile%
if exist visitcmd.bat call visitcmd.bat
find "set VisitFile=" /v < ~visit.tmp > ~visit.lst
goto LoopVisit

:Clear
del ~visit.*
set VisitFile=

:End

3 楼

咦,还挺不错挺利害的.

那就顺便请教一下喽,
有些东西一直没学懂,
就是for的用法.

比如我需要在某个目录下,
把所有文件名以"abc"开头的文件改成"12"开头.
我见过也知道应该可以利用for和变量的,
但不知道具体的参数.
讨教讨教.

4 楼

Ren abc* 12*
把abc开头的改成12c*的

5 楼

这是改多的,不是改少的
这个我知道,否则我怎么会说要用到for?

6 楼

当你的文件名列表输出到文件时,如果你建文件的位置是不可写的,如:光盘
那么你的代码将起不了作用
而Dirs$函数则不必,只要当前路径是可读的,那么将会顺利的执行
而经常地许多储存器是防写入的.

Dirs$ 函数的Path$ 参数一样是可用通配符的
如:
我要搜索 c:\*.TXT 文件则:
ret$=Dirs("C:\*.txt",attr%,size&)

我认为在编程时这个函数应该比较实用些
只是我没在函数里面加上在搜索时遇到的错误信息
但当有错误发生时函数返回的是一个空串

7 楼

输出文件不一定要输到当前盘的,
除非是无盘工作站吧.

为了这一个例程要把QBX快速库一起包含进去,
生成的执行文件体积不划算,

anyway,做得也挺不错.
看来我也得恶补一下汇编和中断
但这些寄存器就没有其它办法读写了吗?

8 楼

有:
用Interruptx调用DOS中断21子功能4E和4F

9 楼

A$=DIR$("abc*")
B$=RIGHT$(A$,LEN(A$-1))
MID$(B$,1,2)="12"
NAME A$ B$
DO
A$=DIR$
IF A$="" THEN EXIT DO
B$=RIGHT$(A$,LEN(A$-1))
MID$(B$,1,2)="12"
NAME A$ B$
LOOP
END

10 楼

TO:def
这个方法我知道的,
但我需要的是在DOS下用for执行,
现在我已经大概了解了了FOR,只是还是不能把握好参数的运用,
在QB中有文件名长度的限制,所以这个程序是没有用的.


TO:  QB71
既然这幢楼又给def盖起来了,
我又忍不住手帮你把程序改了改,
皆因你的代码实在惨不忍睹.
那么多的mid$()=实在是......太过份

'-----------------------------------------------------------------------
'[color=FF00FF]运行QB的时候记得在命令行的最后面加上参数/L[/color]
'这个问题我在论坛发过帖子
'现在这个帖子找不到了
'这是重新优化过的过程
'CALL absolute 过程是由QB45提供的[color=FF00FF]就算是分评功论赏也别要过份到这个样子吧?[/color]
'[color=FF00FF]absolute还能是qb45创作的?不大可能吧?[/color]
'这个过程能够搜索到当前路径下的所有文件名及子目录名(不管文件什么属性)
'如果在根目录,也能够获得分区的卷标名
'------------------------------------------------------------------------

DEFINT A-Z
FUNCTION Dirs$ (path AS STRING, Attr AS INTEGER, Size AS LONG)
'******************************************************
'  搜索目录下的所有文件和文件夹,适用7.1和4.5版本
'  Attr位 8=卷标 16=目录 [color=FF00FF]还有其他124请看参考书[/color]
'  第一次调用时Path为要搜索的路径,第二次调用时Path请置空
'  返回:Attr=文件属性  Size=文件长度
'******************************************************
STATIC Lc AS INTEGER, ErrCode AS INTEGER, FileDATA AS STRING * 44, FirstCode AS STRING * 28, NextCode AS STRING * 18, FileName AS STRING * 64
IF Lc = 0 THEN
   Lc = 1
   DIM AsmCode AS STRING * 12
   AsmCode = CHR$(&H68) + MKI$(VARSEG(FileDATA)) + CHR$(&H1F) + CHR$(&HBA) + MKI$(VARPTR(FileDATA)) + CHR$(&HB4) + CHR$(&H1A) + CHR$(&HCD) + CHR$(&H21) + CHR$(&HCB)
     DEF SEG = VARSEG(AsmCode)
     CALL ABSOLUTE(VARPTR(AsmCode))
     DEF SEG
   FirstCode = STRING$(3, 0) + CHR$(&H1F) + STRING$(3, 0) + CHR$(&HB8) + CHR$(&H0) + CHR$(&H4E) + CHR$(&HB9) + MKI$(255) + CHR$(&HCD) + CHR$(&H21) + CHR$(&H68) + MKI$(VARSEG(ErrCode)) + CHR$(&H1F) + CHR$(&H72) + CHR$(&H2) + CHR$(&H33) + CHR$(&HC0) + _
CHR$(&H3E) + CHR$(&HA3) + MKI$(VARPTR(ErrCode)) + CHR$(&HCB)
   NextCode = CHR$(&HB8) + CHR$(&H0) + CHR$(&H4F) + CHR$(&HCD) + CHR$(&H21) + CHR$(&H68) + MKI$(VARSEG(ErrCode)) + CHR$(&H1F) + CHR$(&H72) + CHR$(&H2) + CHR$(&H33) + CHR$(&HC0) + CHR$(&H3E) + CHR$(&HA3) + MKI$(VARPTR(ErrCode)) + CHR$(&HCB)
END IF

IF path <> "" THEN
   FileName = path + CHR$(0)
   MID$(FirstCode, 1, 3) = CHR$(&H68) + MKI$(VARSEG(FileName))
   MID$(FirstCode, 5, 3) = CHR$(&HBA) + MKI$(VARPTR(FileName))
     DEF SEG = VARSEG(FirstCode)
     CALL ABSOLUTE(VARPTR(FirstCode))
     DEF SEG
   IF ErrCode THEN EXIT FUNCTION
ELSE
     DEF SEG = VARSEG(NextCode)
     CALL ABSOLUTE(VARPTR(NextCode))
     DEF SEG
   IF ErrCode THEN EXIT FUNCTION
END IF

File$ = MID$(FileDATA, 31)
Dirs$ = LEFT$(File$, INSTR(File$, CHR$(0)) - 1)
Attr% = ASC(MID$(FileDATA, 22, 1))
Size& = CVL(MID$(FileDATA, 27, 4))
END FUNCTION

最后我还有一件事很不明白,
记得以前写程序的时候都会记住
A% 和 A$ 和 A 是三个不同的变量,
但在这里虽然是声明过是个静态变量,
但总觉得 path 怎么就变成了 path$ 一样了呢?

我来回复

您尚未登录,请登录后再回复。点此登录或注册