Page 1 of 1

Access to SEVERAL files via Standard Handles

Posted: 27 Mar 2012 04:51
by Aacini
The present topic is based on this one; you should read that topic first.

SETFILEPOINTER.COM program allows to process the lines of a redirected input file in any order, allowing to create a rudimentary Relational Data Base. However, a Batch file is limited to manage just two files: STDIN for input (SET /P) operations, and STDOUT for output (ECHO, etc.) operations. We could made good use of SETFILEPOINTER program in a better way if we could access more than one input and output files in a Batch file. How to do that? In a relatively easy way: just connect the additional files to unused handles (3-9) and use the appropiate handle in the input (SET /P <&#) or output (ECHO >&#) commands.

The Batch file below merge the lines of 3 input files into one output file with larger lines:

Code: Select all

@echo off
setlocal EnableDelayedExpansion
3<input2.txt 4<input3.txt (
for /F "delims=" %%a in (input1.txt) do (
   set line=
   rem Read from input2.txt (and write line from input1 to output.txt):
   set /P line=%%a <&3
   rem Read from input3.txt (and write line from input2 to output.txt):
   set /P line=!line! <&4
   rem Write line from input3 to output.txt:
   echo(!line!
)
) >output.txt
The same method may be used to generate several output files.

NOTE: For some reason SETFILEPOINTER.COM program can NOT move the file pointer of handles 3-9. This means that, although handles 3-9 may be used to sequentially access several input/output files, only handles 0, 1 and 2 can be used for random access. If a program requires more than these 3 random access files, the workaround is simple although cumbersome: each I/O operation in a file with random access must be enclosed in this block: redirect the file to a standard handle: 0 for input, 1 for output; move its file pointer; read/write the desired record. This way, an unlimited number of random access files may be managed in a Batch file.

Below there is a complete example based on (a few) NBA players: the Data Base is comprised of a base data file (NBA-Players) and 2 related data files: Team and College (the Team file have also the Conference field), and several index files: byNumber, byName and byTeam. NBA-Players.txt file contains in each line (record) a NBA player Number, Name and Position fields, and the starting position of the lines where Team and College fields are stored in its corresponding files, separated by arrobas:
NBA-Players.txt wrote: 20@Ray Allen @Guard @0 @0
30@Reggie Evans @Forward@30@14
9@Andre Iguodala@Forward@60@28
7@Lamar Odom @Forward@90@42
19@Beno Udrih @Guard @120@56
Team.txt wrote: Boston Celtics @Eastern
Los Angeles Clippers@Western
Philadelphia 76ers @Eastern
Dallas Mavericks @Western
Milwaukee Bucks @Eastern
College.txt wrote: Connecticut
Iowa
Arizona
Rhode Island
Sempeter
The index files: byNumber.dex, byName.dex and byTeam.dex, just contain the appropiate order of NBA-Players.txt records:

Code: Select all

byNumber.ndx:   byName.ndx:   byTeam.ndx:

98              0             0
65              32            98
131             65            32
0               98            131
32              131           65
The following Batch file (report.bat) display a report of the NBA-Players.txt file in the order given by the first parameter index file. In this case, the relation of the base file and all its related files is hard-coded in the program, but a general DataBase.bat program may be written with the aid of a scheme auxiliary file that describe these relations.

Code: Select all

@echo off
setlocal EnableDelayedExpansion
cls
echo Report of NBA Players %1
echo/
echo NUM. NAME            POSITION  TEAM                  CONFEREN.  COLLEGE
echo/
for /F %%m in (%1.ndx) do (
   <NBA-Players.txt (
   SetFilePointer 0 %%m
   set /P mainRecord=
   )
   for /F "tokens=1-5 delims=@" %%a in ("!mainRecord!") do (
      <Team.txt (
      SetFilePointer 0 %%d
      set /P "team=%%a   %%b  %%c   "
      )
      for /F "tokens=1,2 delims=@" %%x in ("!team!") do (
         set team=%%x
         set conference=%%y
      )
      <College.txt (
      SetFilePointer 0 %%e
      set /P "college=!team!  !conference!    "
      )
      echo !college!
   )
)
echo/
This way, you may execute this command:

Code: Select all

report byName
... with these results:

Code: Select all

Report of NBA Players byName

NUM. NAME            POSITION  TEAM                  CONFEREN.  COLLEGE

20   Ray Allen       Guard     Boston Celtics        Eastern    Connecticut
30   Reggie Evans    Forward   Los Angeles Clippers  Western    Iowa
 9   Andre Iguodala  Forward   Philadelphia 76ers    Eastern    Arizona
 7   Lamar Odom      Forward   Dallas Mavericks      Western    Rhode Island
19   Beno Udrih      Guard     Milwaukee Bucks       Eastern    Sempeter
or this command:

Code: Select all

report byTeam
... with these results:

Code: Select all

Report of NBA Players byTeam

NUM. NAME            POSITION  TEAM                  CONFEREN.  COLLEGE

20   Ray Allen       Guard     Boston Celtics        Eastern    Connecticut
 7   Lamar Odom      Forward   Dallas Mavericks      Western    Rhode Island
30   Reggie Evans    Forward   Los Angeles Clippers  Western    Iowa
19   Beno Udrih      Guard     Milwaukee Bucks       Eastern    Sempeter
 9   Andre Iguodala  Forward   Philadelphia 76ers    Eastern    Arizona
Antonio

Re: Access to SEVERAL files via Standard Handles

Posted: 28 Mar 2012 23:58
by jeb
The idea to use different input streams is smart :D

I suppose, it can be handy

jeb

Re: Access to SEVERAL files via Standard Handles

Posted: 30 Mar 2012 19:49
by Aacini
Thanks, jeb. :)

What do you think about the random access of files in Batch :?:

Perhaps you don't like third-party auxiliary programs. Isn't it?

Antonio

Re: Access to SEVERAL files via Standard Handles

Posted: 30 Mar 2012 20:07
by dbenham
I would love a random access utility, but COM files do not work on 64 bit machines (like mine). They are becoming more prevalent, so COM files are a dying breed.

Can the same functionality be put into JScript or VBScript? Many might say it is silly to write such a utility in JScript or VBScript when the whole app could be written there, and there is a relatively expensive startup performance cost with each call. But such a utility might be useful.

Dave Benham