Operating System - OpenVMS
1748288 Members
3168 Online
108761 Solutions
New Discussion юеВ

Re: Getting block size of a data file, from within COBOL.

 
SOLVED
Go to solution
John T. Farmer
Regular Advisor

Getting block size of a data file, from within COBOL.

Is there an RTL available that returns file-level information (i.e., SYS$, LIB$, etc)? In COBOL, I am processing a file containing a list of data files from my system. I need to get the file size (disk blocks) for each file in my list. Trying to avoid doing this at the DCL level. Also trying to avoid having to open each file and count characters, some are fixed length, and some are variable length RMS files.

Thanks,

John
OpenVMS (Alpha) v7.2-1
Compaq Cobol v2.6-1060
RMS File System
15 REPLIES 15
Kris Clippeleyr
Honored Contributor

Re: Getting block size of a data file, from within COBOL.

John,

> Also trying to avoid having to open each file

Going to be difficult. But you can always open the file using RMS routine $OPEN, specifying a FAB and an associated XABFHC, and immediately closing it again with $CLOSE.
In the XABFHC is returned (among others) XAB$L_EBK (end of file block) and XAB$L_HBK (highest virtual block in the file). That might give you an idea on the size of the file.

Regards,
Kris (aka Qkcl)
I'm gonna hit the highway like a battering ram on a silver-black phantom bike...
Hein van den Heuvel
Honored Contributor
Solution

Re: Getting block size of a data file, from within COBOL.

Unfortunately there is no system provides calleable function like the DCL F$FILE to do this. Several folks have rolled their own. Not sure whether there is a nice package out there.

Cobol really is the worst language to do this in. If this is just for a one-off run then please just use DCL, PERL, C, or BASIC

Cobol does not have a 'flexible' file open (BASIC and C do) which woudl allow you to just open the file and look in that RMS FAB what the size is.

Cobol also does not have proper pointer support play with RMS control blocks, because that is want needs to be done.

You need to craft a FAB, fill in a name, call SYS$OPEN and read the ALQ field in the FAB.

Compare to PERL (which has a 'stat' function)
$ perl -e "print -s ""test.mai"""
8139264

or, if you don't like the double-double quotes:
$ perl -e "print -s q(test.mai)"
8139264


Or DCL
$ write sys$output 512*f$file("test.mai","alq")
8139264

I would cheat and just SPAWN 'directory, perl, dcl or whatever, unless you need it several times per hour.

I have been know to cheat in COBOL and call LIB$FIND_FILE which, indirectly through the CTX points to a FAB which can be hi-jacked.

FDL$PARSE can also be used to make a FAB on the fly from a piece of string.

And if you know enough to be open the file in CObol, then you can ask it kindly where the FAB is and use that (see full example below).

But what problem are you really trying to solve?
What are you going to to, knowing the files allocated sizes? Report and be done? Whoopie!

Or did you want the 'used bytes' ... you'll need to hook up an XABFHC!
Or did you want to know how many data bytes there where?.. count 'm!
(There is an RMS hint to help)

"cobol only" example below...

Cheers,
Hein.

IDENTIFICATION DIVISION.
PROGRAM-ID. HEIN.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT THE-FILE
ASSIGN TO "TEST"
FILE STATUS IS FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD THE-FILE.
01 THE-RECORD.
03 THE-KEY PIC X(4).
03 SOME-DATA PIC X(66).
WORKING-STORAGE SECTION.
01 FILE-STATUS PIC XX.
01 FAB_PT POINTER.
01 ALQ_PT POINTER.
01 ALQ PIC 9(9) COMP VALUE 0.

PROCEDURE DIVISION.

MAIN-CONTROL SECTION.
BEGIN-HERE.
OPEN I-O THE-FILE ALLOWING ALL.
CALL "DCOB$RMS_CURRENT_FAB" GIVING FAB_PT
ADD 16 to FAB_PT GIVING ALQ_PT.
CALL "OTS$MOVE3" USING BY VALUE 4, BY VALUE ALQ_PT, BY REFERENCE ALQ.
DISPLAY "ALQ=", ALQ WITH CONVERSION.

John T. Farmer
Regular Advisor

Re: Getting block size of a data file, from within COBOL.

Hein,

Great example!!! This will give me what I need. The end result is that I will have a file list, several times a month, where I need to report names & sizes. A called routine using your code, does the trick.

Thanks,

John
Hein van den Heuvel
Honored Contributor

Re: Getting block size of a data file, from within COBOL.

>> Great example!!! This will give me what I need.

Hmmm, and here I was thinking I would just throw that in to scare of off!
:-)

The hard-coded '16' in there was found using:

$ libr/extr=$fabdef/out=fabdef.mar sys$library:starlet.mlb
$ sea fabdef.mar _alq
$EQU FAB$L_ALQ 16

Most folks would prefer to neatly declare a 'value is external' symbolic value, but if you had written a Macro program, then a hardoced 16 is really all you would be using.

The hardcoded 4 in the move is of course related to the 4 bytes which a $L = long symbol suggests.

> A called routine using your code, does the trick.

Glad it works for you!
Cheers,

Hein.

John T. Farmer
Regular Advisor

Re: Getting block size of a data file, from within COBOL.

You guys are way smarter than me. I attached my callable program implementing your logic example. Feel free to use and/or critique.

Thanks, John
Richard J Maher
Trusted Contributor

Re: Getting block size of a data file, from within COBOL.

Hi John,

A couple of quick points: -

1) You may want to pass the status to lib$stop By Value

2) A Declaratives section couldn't hurt and you could then crash with the RMS-STS special register.

3) I think there is another option where you could use the the $qio (io$_acp_control? io$_access?) to do a directory lookup of the file and I think the allocation is in the statistics info. (See i/o reference manual and disk driver for more) Probably best to stick with what your currently doing, but with this method I believe IIRC that you can $parse the filename and then get the allocation without ever having opened the file. If you're interested, search this forum for DIR_WATCH for more.

Regards Richard Maher

PS. The Caps-Lock key is on the left side of your keyboard :-)
John T. Farmer
Regular Advisor

Re: Getting block size of a data file, from within COBOL.

RICHARD,

THANK YOU.

JOHN ;)
Pallavi Akundi
Occasional Advisor

Re: Getting block size of a data file, from within COBOL.

Hi,

I might be a bit late.. but well i just became a member. I am a new comer in to this field and here is a program I have written. Please tell me if this works for you :)

I have attached the .cob,

and here is the .COM
DETSIZE.COM
-----------------------------
$FILE = SAMPLE.TXT
$FILE_SIZE = F$FILE_ATTRIBUTES("''FILE'","EOF")
-----------------------------
People with goals succeed because they know where they are going-- as quoted by some one
John T. Farmer
Regular Advisor

Re: Getting block size of a data file, from within COBOL.

Pallavi,

Never too late. That's a nice approach too.

Thanks,

John