[Info-vax] CRTL and RMS vs SSIO

Arne Vajhøj arne at vajhoej.dk
Sat Oct 9 19:47:32 EDT 2021


On 10/7/2021 9:34 AM, Arne Vajhøj wrote:> On 10/7/2021 8:59 AM, Simon 
Clubley wrote:
 >> On 2021-10-07, Greg Tinkler <tinklerg at gmail.com> wrote:
 >>> On Thursday, 7 October 2021 at 11:26:38 pm UTC+11, Simon Clubley wrote:
 >>>> How do you find byte 12,335,456 in a variable length RMS sequential
 >>>> file
 >>>> without reading from the start of the file ?
 >>>>
 >>>> That's why there are restrictions on RMS supported file formats in an
 >>>> application in some cases.
 >>>
 >>> The same way it is done on Unix, calculate the block offset, go get
 >>> it, and extract the byte.  no difference and nothing to do with the
 >>> underlying format.
 >>
 >> You don't know the block offset without scanning the file when it comes
 >> to some RMS file formats.
 >>
 >> IOW, data byte 12,335,456 will not be the same thing as file byte
 >> 12,335,456
 >> unless you restrict yourself to record formats that do not have embedded
 >> record metadata.
 >
 > Yes.
 >
 > And it does not get better when using standard C IO.
 >
 > I suspect that the variable length file output below will
 > surprise a few *nix developers.
I decided to add to the examples. More file types and
more languages.

Fair warning: this will be a long post.

:-)

It will be 3 parts:
- my summary of results
- raw results from test
- source code

Arne


My summary of results
=====================

Traditional record oriented languages (Fortran, Pascal, Basic etc.):
- limited options basically one can read records sequentially and
   file size and offsets from start of file are irrelevant
- always works and the reads return the records with the expected
   content
- the record format does not matter and RMS does a perfect
   encapsulation of actual record format

Languages with a stream oriented view on files (C, Python, Java etc.):
* rfm:stmlf
   - works consistently with all sorts of access and compatible
     with *nix code
* all other rfm (var, vfc, fix and stm)
   - open as text file and sequential read only: works consistently
     and compatible with *nix code, some of the bytes read (LF)
     are not in the file and the number of bytes read does not match
     the file size but it basically works
   - open as binary or try to use seek to arbitrary positions in
     the file or try to use C ctx=stm: not *nix compatible, and
     some of the behavior may surprise even VMS people [note that
     some of the code are deemed unsupported by the VMS documentation,
     but not always easy to find, and even if found for C then
     one may have to guess other languages using CRTL use
     that C function]


Raw results from test
=====================

var.txt Fortran READ: 41 * 42 42 * 43 43 43 * (6 bytes)
var.txt Pascal ReadLn: 41 * 42 42 * 43 43 43 * (6 bytes)
var.txt Basic Input: 41 * 42 42 * 43 43 43 * (6 bytes)
var.txt C size = 14 bytes
var.txt C fgetc (text): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
var.txt C fgetc (binary): 41 42 42 43 43 43 (6 bytes)
var.txt C fseek and fgetc (text): 41 -1 02 -1 42 -1 -1 -1 43 -1 -1 -1 FF 
-1 (14 bytes)
var.txt C fseek and fgetc (binary): 41 -1 02 -1 42 -1 -1 -1 43 -1 -1 -1 
FF -1 (14 bytes)
var.txt C fgets (text): 41 0A * 42 42 0A * 43 43 43 0A * (9 bytes)
var.txt C fgets (binary): 41 42 42 43 43 43 * (6 bytes)
var.txt C fgetc (text stream): 01 00 41 00 02 00 42 42 03 00 43 43 43 00 
(14 bytes)
var.txt C fgetc (binary stream): 01 00 41 00 02 00 42 42 03 00 43 43 43 
00 (14 bytes)
var.txt C fseek and fgetc (text stream): 41 -1 02 -1 42 -1 -1 -1 43 -1 
-1 -1 FF -1 (14 bytes)
var.txt C fseek and fgetc (binary stream): 41 -1 02 -1 42 -1 -1 -1 43 -1 
-1 -1 FF -1 (14 bytes)
var.txt C fgets (text stream): 01 * (1 bytes)
var.txt C fgets (binary stream): 01 * (1 bytes)
var.txt Python size = 14 bytes
var.txt Python read 1 (mode r): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
var.txt Python read 1 (mode rb): 01 00 41 00 02 00 42 42 03 00 43 43 43 
00 (14 bytes)
var.txt Python seek and read 1 (mode r): 41 -1 02 -1 42 -1 -1 -1 43 -1 
-1 -1 FF -1 (14 bytes)
var.txt Python seek and read 1 (mode rb): 01 00 41 00 02 00 42 42 03 00 
43 43 43 00 (14 bytes)
var.txt Python readline (mode r): 41 0A * 42 42 0A * 43 43 43 0A * (9 bytes)
var.txt Python readline (mode rb): 01 00 41 00 02 00 42 42 03 00 43 43 
43 00 * (14 bytes)
var.txt Java size = 14 bytes
var.txt Java InputStream read: 41 0A 42 42 0A 43 43 43 0A (9 bytes)
var.txt Java RandomAccessFile seek and read: 41 -1 02 -1 42 -1 -1 -1 43 
-1 -1 -1 FF -1 (14 bytes)
var.txt Java InputStreamReader read: 41 0A 42 42 0A 43 43 43 0A (9 chars)
var.txt Java BufferedReader readLine: 41 * 42 42 * 43 43 43 * (6 chars)
vfc.txt Fortran READ: 41 * 42 42 * 43 43 43 * (6 bytes)
vfc.txt Pascal ReadLn: 41 * 42 42 * 43 43 43 * (6 bytes)
vfc.txt Basic Input: 41 * 42 42 * 43 43 43 * (6 bytes)
vfc.txt C size = 20 bytes
vfc.txt C fgetc (text): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
vfc.txt C fgetc (binary): 01 8D 41 01 8D 42 42 01 8D 43 43 43 (12 bytes)
vfc.txt C fseek and fgetc (text): 41 0D -1 -1 0A -1 0A 0D -1 -1 -1 -1 0A 
0D -1 -1 -1 -1 00 -1 (20 bytes)
vfc.txt C fseek and fgetc (binary): 01 8D -1 -1 04 -1 01 8D -1 -1 -1 -1 
01 8D -1 -1 -1 -1 FF -1 (20 bytes)
vfc.txt C fgets (text): 41 0A * 42 42 0A * 43 43 43 0A * (9 bytes)
vfc.txt C fgets (binary): 01 -1 41 01 -1 42 42 01 -1 43 43 43 * (12 bytes)
vfc.txt C fgetc (text stream): 03 00 01 8D 41 00 04 00 01 8D 42 42 05 00 
01 8D 43 43 43 00 (20 bytes)
vfc.txt C fgetc (binary stream): 03 00 01 8D 41 00 04 00 01 8D 42 42 05 
00 01 8D 43 43 43 00 (20 bytes)
vfc.txt C fseek and fgetc (text stream): 41 0D -1 -1 0A -1 0A 0D -1 -1 
-1 -1 0A 0D -1 -1 -1 -1 00 -1 (20 bytes)
vfc.txt C fseek and fgetc (binary stream): 01 8D -1 -1 04 -1 01 8D -1 -1 
-1 -1 01 8D -1 -1 -1 -1 FF -1 (20 bytes)
vfc.txt C fgets (text stream): 03 * (1 bytes)
vfc.txt C fgets (binary stream): 03 * (1 bytes)
vfc.txt Python size = 20 bytes
vfc.txt Python read 1 (mode r): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
vfc.txt Python read 1 (mode rb): 03 00 01 8D 41 00 04 00 01 8D 42 42 05 
00 01 8D 43 43 43 00 (20 bytes)
vfc.txt Python seek and read 1 (mode r): 41 0D -1 -1 0A -1 0A 0D -1 -1 
-1 -1 0A 0D -1 -1 -1 -1 00 -1 (20 bytes)
vfc.txt Python seek and read 1 (mode rb): 03 00 01 8D 41 00 04 00 01 8D 
42 42 05 00 01 8D 43 43 43 00 (20 bytes)
vfc.txt Python readline (mode r): 41 0A * 42 42 0A * 43 43 43 0A * (9 bytes)
vfc.txt Python readline (mode rb): 03 00 01 8D 41 00 04 00 01 8D 42 42 
05 00 01 8D 43 43 43 00 * (20 bytes)
vfc.txt Java size = 20 bytes
vfc.txt Java InputStream read: 41 0A 42 42 0A 43 43 43 0A (9 bytes)
vfc.txt Java RandomAccessFile seek and read: 41 0D -1 -1 0A -1 0A 0D -1 
-1 -1 -1 0A 0D -1 -1 -1 -1 00 -1 (20 bytes)
vfc.txt Java InputStreamReader read: 41 0A 42 42 0A 43 43 43 0A (9 chars)
vfc.txt Java BufferedReader readLine: 41 * 42 42 * 43 43 43 * (6 chars)
stmlf.txt Fortran READ: 41 * 42 42 * 43 43 43 * (6 bytes)
stmlf.txt Pascal ReadLn: 41 * 42 42 * 43 43 43 * (6 bytes)
stmlf.txt Basic Input: 41 * 42 42 * 43 43 43 * (6 bytes)
stmlf.txt C size = 9 bytes
stmlf.txt C fgetc (text): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stmlf.txt C fgetc (binary): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stmlf.txt C fseek and fgetc (text): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stmlf.txt C fseek and fgetc (binary): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stmlf.txt C fgets (text): 41 0A * 42 42 0A * 43 43 43 0A * (9 bytes)
stmlf.txt C fgets (binary): 41 0A * 42 42 0A * 43 43 43 0A * (9 bytes)
stmlf.txt C fgetc (text stream): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stmlf.txt C fgetc (binary stream): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stmlf.txt C fseek and fgetc (text stream): 41 0A 42 42 0A 43 43 43 0A (9 
bytes)
stmlf.txt C fseek and fgetc (binary stream): 41 0A 42 42 0A 43 43 43 0A 
(9 bytes)
stmlf.txt C fgets (text stream): 41 0A * 42 42 0A * 43 43 43 0A * (9 bytes)
stmlf.txt C fgets (binary stream): 41 0A * 42 42 0A * 43 43 43 0A * (9 
bytes)
stmlf.txt Python size = 9 bytes
stmlf.txt Python read 1 (mode r): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stmlf.txt Python read 1 (mode rb): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stmlf.txt Python seek and read 1 (mode r): 41 0A 42 42 0A 43 43 43 0A (9 
bytes)
stmlf.txt Python seek and read 1 (mode rb): 41 0A 42 42 0A 43 43 43 0A 
(9 bytes)
stmlf.txt Python readline (mode r): 41 0A * 42 42 0A * 43 43 43 0A * (9 
bytes)
stmlf.txt Python readline (mode rb): 41 0A * 42 42 0A * 43 43 43 0A * (9 
bytes)
stmlf.txt Java size = 9 bytes
stmlf.txt Java InputStream read: 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stmlf.txt Java RandomAccessFile seek and read: 41 0A 42 42 0A 43 43 43 
0A (9 bytes)
stmlf.txt Java InputStreamReader read: 41 0A 42 42 0A 43 43 43 0A (9 chars)
stmlf.txt Java BufferedReader readLine: 41 * 42 42 * 43 43 43 * (6 chars)
stm.txt Fortran READ: 41 * 42 42 * 43 43 43 * (6 bytes)
stm.txt Pascal ReadLn: 41 * 42 42 * 43 43 43 * (6 bytes)
stm.txt Basic Input: 41 * 42 42 * 43 43 43 * (6 bytes)
stm.txt C size = 12 bytes
stm.txt C fgetc (text): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stm.txt C fgetc (binary): 41 42 42 43 43 43 (6 bytes)
stm.txt C fseek and fgetc (text): 41 0A 0A 42 42 0A 0A 43 43 43 0A 0A 
(12 bytes)
stm.txt C fseek and fgetc (binary): 41 42 0A 42 42 43 0A 43 43 43 -1 0A 
(12 bytes)
stm.txt C fgets (text): 41 0A * 42 42 0A * 43 43 43 0A * (9 bytes)
stm.txt C fgets (binary): 41 42 42 43 43 43 * (6 bytes)
stm.txt C fgetc (text stream): 41 0D 0A 42 42 0D 0A 43 43 43 0D 0A (12 
bytes)
stm.txt C fgetc (binary stream): 41 0D 0A 42 42 0D 0A 43 43 43 0D 0A (12 
bytes)
stm.txt C fseek and fgetc (text stream): 41 0A 0A 42 42 0A 0A 43 43 43 
0A 0A (12 bytes)
stm.txt C fseek and fgetc (binary stream): 41 42 0A 42 42 43 0A 43 43 43 
-1 0A (12 bytes)
stm.txt C fgets (text stream): 41 0D 0A * 42 42 0D 0A * 43 43 43 0D 0A * 
(12 bytes)
stm.txt C fgets (binary stream): 41 0D 0A * 42 42 0D 0A * 43 43 43 0D 0A 
* (12 bytes)
stm.txt Python size = 12 bytes
stm.txt Python read 1 (mode r): 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stm.txt Python read 1 (mode rb): 41 0D 0A 42 42 0D 0A 43 43 43 0D 0A (12 
bytes)
stm.txt Python seek and read 1 (mode r): 41 0A 0A 42 42 0A 0A 43 43 43 
0A 0A (12 bytes)
stm.txt Python seek and read 1 (mode rb): 41 0D 0A 42 42 0D 0A 43 43 43 
0D 0A (12 bytes)
stm.txt Python readline (mode r): 41 0A * 42 42 0A * 43 43 43 0A * (9 bytes)
stm.txt Python readline (mode rb): 41 0D 0A * 42 42 0D 0A * 43 43 43 0D 
0A * (12 bytes)
stm.txt Java size = 12 bytes
stm.txt Java InputStream read: 41 0A 42 42 0A 43 43 43 0A (9 bytes)
stm.txt Java RandomAccessFile seek and read: 41 0A 0A 42 42 0A 0A 43 43 
43 0A 0A (12 bytes)
stm.txt Java InputStreamReader read: 41 0A 42 42 0A 43 43 43 0A (9 chars)
stm.txt Java BufferedReader readLine: 41 * 42 42 * 43 43 43 * (6 chars)
fix2.txt Fortran READ: 41 41 * 42 42 * 43 43 * (6 bytes)
fix2.txt Pascal ReadLn: 41 41 * 42 42 * 43 43 * (6 bytes)
fix2.txt Basic Input: 41 41 * 42 42 * 43 43 * (6 bytes)
fix2.txt C size = 6 bytes
fix2.txt C fgetc (text): 41 41 0A 42 42 0A 43 43 0A (9 bytes)
fix2.txt C fgetc (binary): 41 41 42 42 43 43 (6 bytes)
fix2.txt C fseek and fgetc (text): 41 41 42 42 43 43 (6 bytes)
fix2.txt C fseek and fgetc (binary): 41 41 42 42 43 43 (6 bytes)
fix2.txt C fgets (text): 41 41 0A * 42 42 0A * 43 43 0A * (9 bytes)
fix2.txt C fgets (binary): 41 41 42 42 43 43 * (6 bytes)
fix2.txt C fgetc (text stream): 41 41 42 42 43 43 (6 bytes)
fix2.txt C fgetc (binary stream): 41 41 42 42 43 43 (6 bytes)
fix2.txt C fseek and fgetc (text stream): 41 41 42 42 43 43 (6 bytes)
fix2.txt C fseek and fgetc (binary stream): 41 41 42 42 43 43 (6 bytes)
fix2.txt C fgets (text stream): 41 41 42 42 43 43 * (6 bytes)
fix2.txt C fgets (binary stream): 41 41 42 42 43 43 * (6 bytes)
fix2.txt Python size = 6 bytes
fix2.txt Python read 1 (mode r): 41 41 0A 42 42 0A 43 43 0A (9 bytes)
fix2.txt Python read 1 (mode rb): 41 41 42 42 43 43 (6 bytes)
fix2.txt Python seek and read 1 (mode r): 41 41 42 42 43 43 (6 bytes)
fix2.txt Python seek and read 1 (mode rb): 41 41 42 42 43 43 (6 bytes)
fix2.txt Python readline (mode r): 41 41 0A * 42 42 0A * 43 43 0A * (9 
bytes)
fix2.txt Python readline (mode rb): 41 41 42 42 43 43 * (6 bytes)
fix2.txt Java size = 6 bytes
fix2.txt Java InputStream read: 41 41 0A 42 42 0A 43 43 0A (9 bytes)
fix2.txt Java RandomAccessFile seek and read: 41 41 42 42 43 43 (6 bytes)
fix2.txt Java InputStreamReader read: 41 41 0A 42 42 0A 43 43 0A (9 chars)
fix2.txt Java BufferedReader readLine: 41 41 * 42 42 * 43 43 * (6 chars)
fix1.txt Fortran READ: 41 * 42 * 43 * (3 bytes)
fix1.txt Pascal ReadLn: 41 * 42 * 43 * (3 bytes)
fix1.txt Basic Input: 41 * 42 * 43 * (3 bytes)
fix1.txt C size = 6 bytes
fix1.txt C fgetc (text): 41 0A 42 0A 43 0A (6 bytes)
fix1.txt C fgetc (binary): 41 42 43 (3 bytes)
fix1.txt C fseek and fgetc (text): 41 00 42 00 43 00 (6 bytes)
fix1.txt C fseek and fgetc (binary): 41 00 42 00 43 00 (6 bytes)
fix1.txt C fgets (text): 41 0A * 42 0A * 43 0A * (6 bytes)
fix1.txt C fgets (binary): 41 42 43 * (3 bytes)
fix1.txt C fgetc (text stream): 41 00 42 00 43 00 (6 bytes)
fix1.txt C fgetc (binary stream): 41 00 42 00 43 00 (6 bytes)
fix1.txt C fseek and fgetc (text stream): 41 00 42 00 43 00 (6 bytes)
fix1.txt C fseek and fgetc (binary stream): 41 00 42 00 43 00 (6 bytes)
fix1.txt C fgets (text stream): 41 * (1 bytes)
fix1.txt C fgets (binary stream): 41 * (1 bytes)
fix1.txt Python size = 6 bytes
fix1.txt Python read 1 (mode r): 41 0A 42 0A 43 0A (6 bytes)
fix1.txt Python read 1 (mode rb): 41 00 42 00 43 00 (6 bytes)
fix1.txt Python seek and read 1 (mode r): 41 00 42 00 43 00 (6 bytes)
fix1.txt Python seek and read 1 (mode rb): 41 00 42 00 43 00 (6 bytes)
fix1.txt Python readline (mode r): 41 0A * 42 0A * 43 0A * (6 bytes)
fix1.txt Python readline (mode rb): 41 00 42 00 43 00 * (6 bytes)
fix1.txt Java size = 6 bytes
fix1.txt Java InputStream read: 41 0A 42 0A 43 0A (6 bytes)
fix1.txt Java RandomAccessFile seek and read: 41 00 42 00 43 00 (6 bytes)
fix1.txt Java InputStreamReader read: 41 0A 42 0A 43 0A (6 chars)
fix1.txt Java BufferedReader readLine: 41 * 42 * 43 * (3 chars)

Source code
===========

       program process
       character*256 fnm
       integer*4 fnmlen
       call lib$get_foreign(fnm,,fnmlen)
       call records(fnm(1:fnmlen))
       end
c
       subroutine records(fnm)
       character*(*) fnm
       character*256 res, line
       integer*4 reslen, linelen, ix, i
       res(1:len(fnm)+14) = fnm //' Fortran READ:'
       reslen = len(fnm) + 14
       open(unit=1,file=fnm,status='old')
       ix = 0
100   read(unit=1,fmt='(Q,A)',END=300) LINELEN,LINE
       do 200 i = 1,linelen
         write(res(reslen+1:reslen+3),'(1X,Z2)') ichar(line(i:i))
         reslen = reslen + 3
200   continue
       res(reslen+1:reslen+2) = ' *'
       reslen = reslen + 2
       ix = ix + linelen
       goto 100
300   if(ix.lt.10) then
         write(res(reslen+1:reslen+10),'('' ('',I1,'' bytes)'')') ix
         reslen = reslen + 10
       else
         write(res(reslen+1:reslen+11),'('' ('',I2,'' bytes)'')') ix
         reslen = reslen + 11
       end if
       write(unit=6,fmt='(1X,A)') res(1:reslen)
       close(unit=1)
       return
       end

[inherit('sys$library:pascal$lib_routines')]
program process_p(input,output);

type
    pstring = varying[256] of char;

procedure records(fnm : pstring);

var
    f : text;
    line : pstring;
    ix, i : integer;

begin
    write(fnm, ' Pascal ReadLn:');
    open(f, fnm, old);
    reset(f);
    ix := 0;
    while not eof(f) do begin
       readln(f, line);
       for i := 1 to line.length do begin
          write(' ', hex(ord(line[i]), 2));
       end;
       write(' *');
       ix := ix + line.length;
    end;
    close(f);
    writeln(' (', ix:1, ' bytes)');;
end;

var
    fnm : pstring;

begin
    lib$get_foreign(fnm.body, , fnm.length);
    records(fnm);
end.

program process

declare string fnm

call lib$get_foreign(fnm)
call records(fnm)

end program
!
sub records(string fnm)

declare string res
declare string lin
declare integer ix
declare integer i

external string function hex(integer)

res = fnm + " Basic Input:"
open fnm for input as file #1, recordtype any
ix = 0
handler eof_handler
end handler
when error use eof_handler
     while 1 = 1
         input #1,lin
         ix = ix + len(lin)
         for i = 1 to len(lin)
             res = res + " " + hex(ascii(mid$(lin, i, 1)))
         next i
         res = res + " *"
     next
end when
close #1
res = res + " (" + str$(ix) + " bytes)"
print res

end sub
!
function string hex(integer v)

declare string hexdigit(0 to 15)

hexdigit(0) = "0"
hexdigit(1) = "1"
hexdigit(2) = "2"
hexdigit(3) = "3"
hexdigit(4) = "4"
hexdigit(5) = "5"
hexdigit(6) = "6"
hexdigit(7) = "7"
hexdigit(8) = "8"
hexdigit(9) = "9"
hexdigit(10) = "10"
hexdigit(11) = "11"
hexdigit(12) = "12"
hexdigit(13) = "13"
hexdigit(14) = "14"
hexdigit(15) = "15"

hex = hexdigit(v / 16) + hexdigit(mod(v, 16))

end function

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

void dump(int c)
{
     if(c >= 0)
         printf(" %02X", c);
     else
         printf(" -1");
}

void bytes(const char *fnm, int binmode, int stm)
{
     FILE *fp;
     int ix, c;
     printf("%s C fgetc (%s%s):", fnm, binmode ? "binary" : "text", stm 
? " stream" : "");
     if(!stm)
         fp = fopen(fnm, binmode ? "rb" : "r");
     else
         fp = fopen(fnm, binmode ? "rb" : "r", "ctx=stm");
     ix = 0;
     while((c = fgetc(fp)) >= 0)
     {
         ix++;
         dump(c);
     }
     printf(" (%d bytes)\n", ix);
     fclose(fp);
}

void positionbytes(const char *fnm, int binmode, int stm, int siz)
{
     FILE *fp;
     int ix, c;
     printf("%s C fseek and fgetc (%s%s):", fnm, binmode ? "binary" : 
"text", stm ? " stream" : "");
     if(!stm)
         fp = fopen(fnm, binmode ? "rb" : "r");
     else
         fp = fopen(fnm, binmode ? "rb" : "r");
     for(ix = 0; ix < siz; ix++)
     {
         fseek(fp, ix, SEEK_SET);
         c = fgetc(fp);
         dump(c);
     }
     printf(" (%d bytes)\n", ix);
     fclose(fp);
}

void lines(const char *fnm, int binmode, int stm)
{
     FILE *fp;
     char line[256];
     int ix, i;
     printf("%s C fgets (%s%s):", fnm, binmode ? "binary" : "text", stm 
? " stream" : "");
     if(!stm)
         fp = fopen(fnm, binmode ? "rb" : "r");
     else
         fp = fopen(fnm, binmode ? "rb" : "r", "ctx=stm");
     ix = 0;
     while(fgets(line, sizeof(line), fp))
     {
         ix += strlen(line);
         for(i = 0; i < strlen(line); i++) dump(line[i]);
         printf(" *");
     }
     printf(" (%d bytes)\n", ix);
     fclose(fp);
}

int main(int argc,char *argv[])
{
     struct stat buf;
     stat(argv[1], &buf);
     printf("%s C size = %d bytes\n", argv[1], (int)buf.st_size);
     bytes(argv[1], 0, 0);
     bytes(argv[1], 1, 0);
     positionbytes(argv[1], 0, 0, (int)buf.st_size);
     positionbytes(argv[1], 1, 0, (int)buf.st_size);
     lines(argv[1], 0, 0);
     lines(argv[1], 1, 0);
     bytes(argv[1], 0, 1);
     bytes(argv[1], 1, 1);
     positionbytes(argv[1], 0, 1, (int)buf.st_size);
     positionbytes(argv[1], 1, 1, (int)buf.st_size);
     lines(argv[1], 0, 1);
     lines(argv[1], 1, 1);
     return 0;
}

import os
import sys

def dump(c):
     if len(c) > 0:
         return format(ord(c[0]), '02X')
     else:
         return '-1'

def bytes(fnm, mode):
     res = '%s Python read 1 (mode %s):' % (fnm, mode)
     f = open(fnm, mode)
     ix = 0
     while True:
         c = f.read(1)
         if not c:
             break
         ix = ix + 1
         res = res + ' ' + dump(c)
     f.close()
     res = res + ' (%d bytes)' % (ix)
     print(res)

def positionbytes(fnm, mode, siz):
     res = '%s Python seek and read 1 (mode %s):' % (fnm, mode)
     f = open(fnm, mode)
     for ix in range(siz):
         try:
             f.seek(ix)
             c = f.read(1)
             res = res + ' ' + dump(c)
         except (IOError):
             res = res + ' -1'
     f.close()
     res = res + ' (%d bytes)' % (siz)
     print(res)

def lines(fnm, mode):
     res = '%s Python readline (mode %s):' % (fnm, mode)
     f = open(fnm, mode)
     ix = 0
     while True:
         line = f.readline()
         if not line:
             break
         for c in line:
             ix = ix + 1
             res = res + ' ' + dump(c)
         res = res + ' *'
     f.close()
     res = res + ' (%d bytes)' % (ix)
     print(res)

print('%s Python size = %d bytes' % (sys.argv[1], 
os.path.getsize(sys.argv[1])))
bytes(sys.argv[1], 'r')
bytes(sys.argv[1], 'rb')
positionbytes(sys.argv[1], 'r', os.path.getsize(sys.argv[1]))
positionbytes(sys.argv[1], 'rb', os.path.getsize(sys.argv[1]))
lines(sys.argv[1], 'r')
lines(sys.argv[1], 'rb')

import java.io.*;

public class Process {
     private static void dump(int c) {
         if(c >= 0) {
             System.out.printf(" %02X", c);
         } else {
             System.out.print(" -1");
         }
     }
     public static void bytes(String fnm) throws IOException {
         System.out.printf("%s Java InputStream read:", fnm);
         InputStream is = new FileInputStream(fnm);
         int ix = 0;
         int c;
         while((c = is.read()) >= 0) {
             ix++;
             dump(c);
         }
         is.close();
         System.out.printf(" (%d bytes)\n", ix);
     }
     public static void positionbytes(String fnm, long siz) throws 
IOException {
         System.out.printf("%s Java RandomAccessFile seek and read:", fnm);
         RandomAccessFile raf = new RandomAccessFile(fnm, "r");
         for(int ix = 0; ix < siz; ix++) {
             try {
                 raf.seek(ix);
                 int c = raf.read();
                 dump(c);
             } catch(IOException ex) {
                 System.out.print(" -1");
             }
         }
         raf.close();
         System.out.printf(" (%d bytes)\n", siz);
     }
     public static void chars(String fnm) throws IOException {
         System.out.printf("%s Java InputStreamReader read:", fnm);
         InputStreamReader isr = new InputStreamReader(new 
FileInputStream(fnm));
         int ix = 0;
         int c;
         while((c = isr.read()) >= 0) {
             ix++;
             dump(c);
         }
         isr.close();
         System.out.printf(" (%d chars)\n", ix);
     }
     public static void lines(String fnm) throws IOException {
         System.out.printf("%s Java BufferedReader readLine:", fnm);
         BufferedReader br = new BufferedReader(new 
InputStreamReader(new FileInputStream(fnm)));
         int ix = 0;
         String line;
         while((line = br.readLine()) != null) {
             for(int i = 0; i < line.length(); i++) {
                 ix++;
                 dump(line.charAt(i));
             }
             System.out.printf(" *");
         }
         br.close();
         System.out.printf(" (%d chars)\n", ix);
     }
     public static void main(String[] args) throws IOException {
         try {
             System.out.printf("%s Java size = %d bytes\n", args[0], 
(new File(args[0])).length());
             bytes(args[0]);
             positionbytes(args[0], (new File(args[0])).length());
             chars(args[0]);
             lines(args[0]);
         } catch(Exception ex) {
             ex.printStackTrace();
         }
     }
}







More information about the Info-vax mailing list