主题:[原创]一个老问题:搜索文件(包含子目录名)
QB71
[专家分:1300] 发布于 2005-05-28 12:58:00
'这个问题我在论坛发过帖子
'现在这个帖子找不到了
'这是重新优化过的过程
'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个回复)
沙发
xyaxw [专家分:40] 发布于 2005-05-28 16:56:00
谢谢
板凳
def [专家分:3380] 发布于 2005-05-28 20:34:00
:: 还有批处理的。。。
:: 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 楼
moz [专家分:37620] 发布于 2005-05-28 21:24:00
咦,还挺不错挺利害的.
那就顺便请教一下喽,
有些东西一直没学懂,
就是for的用法.
比如我需要在某个目录下,
把所有文件名以"abc"开头的文件改成"12"开头.
我见过也知道应该可以利用for和变量的,
但不知道具体的参数.
讨教讨教.
4 楼
def [专家分:3380] 发布于 2005-05-29 12:39:00
Ren abc* 12*
把abc开头的改成12c*的
5 楼
moz [专家分:37620] 发布于 2005-05-29 13:41:00
这是改多的,不是改少的
这个我知道,否则我怎么会说要用到for?
6 楼
QB71 [专家分:1300] 发布于 2005-05-29 18:17:00
当你的文件名列表输出到文件时,如果你建文件的位置是不可写的,如:光盘
那么你的代码将起不了作用
而Dirs$函数则不必,只要当前路径是可读的,那么将会顺利的执行
而经常地许多储存器是防写入的.
Dirs$ 函数的Path$ 参数一样是可用通配符的
如:
我要搜索 c:\*.TXT 文件则:
ret$=Dirs("C:\*.txt",attr%,size&)
我认为在编程时这个函数应该比较实用些
只是我没在函数里面加上在搜索时遇到的错误信息
但当有错误发生时函数返回的是一个空串
7 楼
moz [专家分:37620] 发布于 2005-05-29 22:38:00
输出文件不一定要输到当前盘的,
除非是无盘工作站吧.
为了这一个例程要把QBX快速库一起包含进去,
生成的执行文件体积不划算,
anyway,做得也挺不错.
看来我也得恶补一下汇编和中断
但这些寄存器就没有其它办法读写了吗?
8 楼
QB71 [专家分:1300] 发布于 2005-05-30 15:03:00
有:
用Interruptx调用DOS中断21子功能4E和4F
9 楼
def [专家分:3380] 发布于 2005-07-11 01:05:00
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 楼
moz [专家分:37620] 发布于 2005-07-11 02:38:00
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$ 一样了呢?
我来回复