Examples of Loading MS-DOS Directory Listing into an Array

Застереження щодо списаного вмісту бази знань

У цій статті описано продукти, які корпорація Майкрософт більше не підтримує. Тому ця стаття пропонується "як є" та більше не оновлюватиметься.

Summary

This article discusses three different methods of putting an MS-DOS disk directory listing into a string array.


Example 1 demonstrates how to use the DIR$ function to read a directory listing into an array. This is probably the simplest method for use with Visual Basic for MS-DOS. The DIR$ functions was introduced in Microsoft Basic PDS for MS-DOS and MS OS/2, version 7.0. For an example of using the DIR$ function (which works in both MS-DOS and MS OS/2), query the Knowledge Base on the following keywords:
7.0 and "DIR$" and DIRECTORY and LISTING
Example 2 shows a simple method to SHELL to the MS-DOS DIR command, redirect the output to a file, and input from the file into string variables.


Example 3 below shows how to load an MS-DOS disk directory listing into a string array, using the CALL INTERRUPT statement to invoke the MS-DOS operating-system Interrupt 21h, with functions 1Ah (SetDTA), 4Eh (FindFirst), and 4Fh (FindNext).

More Information

For an example of calling the MS-DOS interrupt functions to obtain disk directory information in Microsoft QuickBasic for MS-DOS, versions 2.0, 2.01, or 3.0, query the Knowledge Base on the following keywords:
INT86.OBJ and FINDFIRST
For a Microsoft Basic PDS for MS-DOS and MS OS/2, version 7.0 or 7.1 or Microsoft Basic Compiler for MS-DOS and MS OS/2, version 6.0 or 6.0b example that displays directory information in MS OS/2 protected mode, query the Knowledge Base on the following keywords:
DosFindFirst or DosFindNext

Example 1

' To try this example in VBDOS.EXE:
' 1. From the File menu, choose New Project.
' 2. Copy the code example to the Code window.
' 3. Press F5 to run the program.
DEFINT A-Z
CONST TRUE = -1
CONST FALSE = NOT TRUE
NumFiles = 255 ' Maximum number of filenames to hold.
Counter = 0
Finished = FALSE
DIM FileName$(NumFiles)

CLS ' Enter DIR type filespec, for example "C:\*.BAS":
INPUT "Enter filespec:"; Path$
TempName$ = DIR$(Path$) ' Get the first filename.
IF TempName$ = "" THEN
PRINT "No file(s) found"
ELSE
FileName$(Counter) = TempName$ ' Keep getting filenames until we
Counter = Counter + 1 ' have NumFiles worth or we get
DO ' them all.
TempName$ = DIR$
IF TempName$ <> "" THEN FileName$(Counter) = TempName$
Counter = Counter + 1
LOOP WHILE TempName$ <> "" AND Counter <= NumFiles
END IF
IF FileName$(0) <> "" THEN ' Display filenames if we received
Counter = 0 ' any.
DO
PRINT FileName$(Counter)
IF FileName$(Counter) = "" THEN Finished = TRUE
Counter = Counter + 1
LOOP WHILE Counter <= NumFiles AND NOT Finished
END IF
END

Example 2

' To try this example in VBDOS.EXE:
' 1. From the File menu, choose New Project.
' 2. Copy the code example to the Code window.
' 3. Press F5 to run the program.
'
' This example works in QuickBasic for MS-DOS, versions 2.0, 2.01, 3.0,
' 4.0, 4.0b, and 4.5; and Basic Compiler for MS-DOS and MS OS/2,
' versions 6.0 and 6.0b; and Basic PDS for MS-DOS and MS OS/2,
' versions 7.0 and 7.1.

nf = 200 ' Handles directory listing up to 200 lines.
DIM buffer$(nf)
INPUT "Enter Search Path: ", path$ ' Enter path such as c:
SHELLSTRING$ = "dir " + path$ + " >dirfile.dat"
SHELL SHELLSTRING$ ' SHELL to the MS-DOS DIRectory command.
OPEN "dirfile.dat" FOR INPUT AS #1
pntr% = 0
WHILE NOT EOF(1) AND pntr% < nf
pntr% = pntr% + 1
INPUT #1, buffer$(pntr%) ' Inputs one directory line at a time.
PRINT buffer$(pntr%)
WEND
CLOSE #1
KILL "dirfile.dat"
END

Example 3

' To try this example in VBDOS.EXE:
' 1. From the File menu, choose New Project.
' 2. Copy the code example to the Code window.
' 3. Press F5 to run the program.

' To run this program in the environment, you must invoke the
' environment with the /L switch to load the default Quick library:
' VBDOS.EXE /L for Visual Basic 1.0 for MS-DOS

' Use the following include file for Visual Basic 1.0 for MS-DOS:
REM $INCLUDE: 'VBDOS.BI'
' This examples works in QuickBasic for MS-DOS, versions 4.0, 4.0b,
' and 4.0; and Basic Compiler for MS-DOS and MS OS/2 (real mode only),
' versions 6.0 and 6.0b.

' Use the following include file for QuickBasic for MS-DOS:
REM $INCLUDE: 'QB.BI'

TYPE FileFindBuf
dos AS STRING * 21
Attributes AS STRING * 1
CreateTime AS INTEGER
AccessDate AS INTEGER
FileSize AS LONG
FileName AS STRING * 13
END TYPE
TYPE FileInfo
FileName AS STRING * 13
Size AS STRING * 8
Seconds AS STRING * 4
Minutes AS STRING * 4
Hours AS STRING * 4
Day AS STRING * 4
Month AS STRING * 4
Year AS STRING * 5
END TYPE
DIM BUFFER AS FileFindBuf
DIM FileInfoBlock(100) AS FileInfo
DECLARE SUB intbuf (BUFFER AS FileFindBuf)
DECLARE SUB setdta (BUFFER AS FileFindBuf)
DECLARE FUNCTION firstfm! (path$, fa%)
DECLARE FUNCTION nextfm ()
DECLARE SUB CalculateAssign (FileInfoBlock() AS ANY, BUFFER AS ANY,_
counter!)
DECLARE SUB PrintDirList (FileInfoBlock() AS ANY, i!)
CLS : CALL setdta(BUFFER)
INPUT "Enter the files spec: "; path$
fa% = 0 ' A value of 16 includes directory names.
counter = 0
IF (firstfm(path$, fa%) = 0) THEN
DO
counter = counter + 1
CalculateAssign FileInfoBlock(), BUFFER, counter
CALL setdta(BUFFER)
LOOP WHILE (nextfm = 0)
END IF

CLS
FOR i = 1 TO counter
PrintDirList FileInfoBlock(), i
NEXT i

END

SUB CalculateAssign (FileInfoBlock() AS FileInfo, _
BUFFER AS FileFindBuf, counter)
FileInfoBlock(counter).FileName = BUFFER.FileName
FileInfoBlock(counter).Size = STR$(BUFFER.FileSize)
FileInfoBlock(counter).Seconds = STR$(BUFFER.CreateTime AND &H1F)
FileInfoBlock(counter).Minutes = _
STR$((BUFFER.CreateTime AND &H7E0) \ 32)
' If BUFFER.CreateTime is negative add 64K to make unsigned integer:
IF BUFFER.CreateTime < 0 THEN
FileInfoBlock(counter).Hours = _
STR$(((BUFFER.CreateTime + 2 ^ 16) AND &HF800) \ 2048)
ELSE
FileInfoBlock(counter).Hours = _
STR$((BUFFER.CreateTime AND &HF800) \ 2048)
END IF
FileInfoBlock(counter).Day = STR$(BUFFER.AccessDate AND &H1F)
FileInfoBlock(counter).Month = _
STR$((BUFFER.AccessDate \ 32) AND &HF)
FileInfoBlock(counter).Year = _
STR$((BUFFER.AccessDate \ 512) + 1980)
END SUB

FUNCTION firstfm (path$, fa%)
DIM inreg AS regtypeX, outreg AS regtypeX
' Use regtype for QuickBasic.
inreg.ax = &H4E00
inreg.cx = fa%
FileName$ = path$ + CHR$(0)
inreg.dx = SADD(FileName$)
inreg.ds = SSEG(FileName$)
' Use CALL INTERRUPT in QuickBasic for MS-DOS.
CALL INTERRUPTX (&H21, inreg, outreg)
firstfm = (outreg.ax AND &HF)
END FUNCTION

SUB intbuf (BUFFER AS FileFindBuf) STATIC
' The first 20 bytes are reserved for MS-DOS and are unchanged.
BUFFER.CreateTime = 0
BUFFER.Attributes = " "
BUFFER.AccessDate = 0
BUFFER.FileSize = 0
BUFFER.FileName = STRING$(13, 32)
END SUB

FUNCTION nextfm
DIM inreg AS regtype, outreg AS regtype
inreg.ax = &H4F00
CALL interrupt(&H21, inreg, outreg)
nextfm = outreg.ax AND &HF
END FUNCTION

SUB PrintDirList (FileInfoBlock() AS FileInfo, i)
PRINT FileInfoBlock(i).FileName;
PRINT SPACE$(5); FileInfoBlock(i).Size;
PRINT SPACE$(5); RTRIM$(LTRIM$(FileInfoBlock(i).Month)) + "-";
IF LEN(RTRIM$(LTRIM$(FileInfoBlock(i).Day))) = 1 THEN
FileInfoBlock(i).Day = "0" + LTRIM$(FileInfoBlock(i).Day)
END IF
PRINT RTRIM$(LTRIM$(FileInfoBlock(i).Day)) + "-";
PRINT RTRIM$(LTRIM$(FileInfoBlock(i).Year));
IF VAL(FileInfoBlock(i).Hours) = 0 THEN
FileInfoBlock(i).Hours = STR$(12) ' Change midnight from 0 to 12.
END IF
IF VAL(FileInfoBlock(i).Hours) > 12 THEN
x% = VAL(FileInfoBlock(i).Hours) - 12
FileInfoBlock(i).Hours = STR$(x%)
suffix$ = "p"
ELSE
suffix$ = "a"
END IF
IF VAL(FileInfoBlock(i).Hours) = 12 AND_
VAL(FileInfoBlock(i).Minutes) > 0 THEN
suffix$ = "p"
END IF
IF LEN(RTRIM$(LTRIM$(FileInfoBlock(i).Hours))) = 1 THEN
t% = 7
ELSE
t% = 6
END IF
PRINT SPACE$(t%); RTRIM$(LTRIM$(FileInfoBlock(i).Hours)) + ":";
IF LEN(RTRIM$(LTRIM$(FileInfoBlock(i).Minutes))) = 1 THEN
FileInfoBlock(i).Minutes = "0" + LTRIM$(FileInfoBlock(i).Minutes)
END IF
PRINT RTRIM$(LTRIM$(FileInfoBlock(i).Minutes));
PRINT suffix$
END SUB

SUB setdta (BUFFER AS FileFindBuf) STATIC
DIM inreg AS regtypex, outreg AS regtypex
CALL intbuf(BUFFER)
inreg.ax = &H1A00
inreg.ds = VARSEG(BUFFER)
inreg.dx = VARPTR(BUFFER)
CALL interruptx(&H21, inreg, outreg)
END SUB
Властивості

Ідентифікатор статті: 41447 – останній перегляд: 16 серп. 2005 р. – виправлення: 1

Зворотний зв’язок