Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
STREAM I/O questions
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  10 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
John  
View profile  
 More options Jun 26 2009, 4:13 am
Newsgroups: comp.lang.fortran
From: John <urbanj...@comcast.net>
Date: Fri, 26 Jun 2009 01:13:31 -0700 (PDT)
Local: Fri, Jun 26 2009 4:13 am
Subject: STREAM I/O questions
! I have a number of Fortran codes (mostly graphics-related or special
! text-based utilities) that need stream I/O. C was the dominant
stream-I/O
! based language; so "When in Rome, do as the Romans do." seemed like
a
! good idea; so when available (as in gfortran/g95) I used the "C-
like"
! extensions:
!
!    ftell, fseek, fputc, fgetc, fget, fput
! As described at
!    http://gcc.gnu.org/onlinedocs/gcc-4.2.4/gfortran/FTELL.html
!
! or called C from Fortran and make look-alikes for the routines.
There
! were a few bumps along the way (in some programming environments (in
! the past?) mixing C and Fortran I/O  (heck, just mixing C and
Fortran)
! was fraught with peril.
!
! As g95(1) and other compilers have now implemented the F2003 stream
! I/O interface, I thought I could now make standard-based routines
with
! the same functionality (just using Fortran 2003; not the
ISO_C_BINDING
! interface to call C).
!
! So if I open a NAMED file with ACCESS="STREAM" it is quite straight-
forward.
! I can use reads and writes with POS= to do what FSEEK(3F) does; I
can use
!    INQUIRE(UNIT=nn,POS=itell)
!    itell=itell-1
! to replace FTELL(3F); and (for NAMED files that I opened) a simple
!    WRITE(nn,'(a)') char  --> FPUTC(3F)
!    READ(nn,'(a)') char   --> FGETC(3F)
!
! But I can't figure out a standard method of making the files pre-
assigned
! to standard input and standard output (and stderr and other pre-
assigned
! files too, I suppose) use stream I/O.
!
!
! Here is a simple demo. program I have to kludge to write to standard
! output, for example:
!-------------------------------------------------------------------------- -----
! read entire file into memory as a stream and write it in reverse
byte order
program rev_file

!
! access computing environment
USE ISO_FORTRAN_ENV, ONLY : ERROR_UNIT,INPUT_UNIT,OUTPUT_UNIT
implicit none
   character(len=1024) :: filein
   character(len=1024) :: fileout
   character(len=1),allocatable :: text(:)
   integer :: ios
   integer :: iputunit=16

   if(command_argument_count() < 1 .or. command_argument_count() .gt.
2 )then
     call stderr('usage: rev inputfile [outputfile]')
     stop
   elseif(command_argument_count() .eq. 2)then
      ! get output filename
      call get_command_argument(2,fileout)
      ! open named file in stream mode positioned to append
      open (unit=iputunit,                  &
      & file=fileout(:len_trim(fileout)),   &
      & access='stream')
      iputunit=16
   else
      iputunit=6
   endif

   ! call with each token from the command line
   call GET_COMMAND_ARGUMENT(1, filein)
   ! allocate character array and copy file into it
   call juslurp(filein,text)
   if(command_argument_count() .eq. 1)then
      ! KLUDGE
      ! write file reversed to stdout
      write(*,'(2000000000000000a:)',advance='no')text(size(text):
1:-1)
   else
      ! write file reversed to a non-preassigned file
      write(iputunit)text(size(text):1:-1)
   endif

   ! release memory
   deallocate(text)
   close(16, iostat=ios)
!-------------------------------------------------------------------------- -----
   contains
   ! allocate text() and read file filename into it
   subroutine juslurp(filename,text)
!-------------------------------------------------------------------------- -----
!  read an entire file into memory as a stream
!  comment: never casually read an entire file into memory if you can
!           process it per line or in smaller units; as large files
can
!           consume unreasonable amounts of memory. What if someone
feeds
!           in a file ten times bigger than you system memory, for
example (even accidently?)
!
!  consider what happens on machines where more than one character is
used
!  for an end-of-line or a character string is used for an internal
file
!  seperator (usually for "multi-file" files, which were once
common)!
!-------------------------------------------------------------------------- -----
      implicit none
      ! filename to shlep
      character(len=*),intent(in) :: filename
      ! array to hold file
      character(len=1),allocatable,intent(out) :: text(:)
      integer :: nchars
      ! use newunit=igetunit in f08
      integer,parameter :: igetunit=15
      integer :: ios

      ! open named file in stream mode positioned to append
      open (unit=igetunit,                  &
      & file=filename(:len_trim(filename)), &
      & access='stream',                    &
      & position='append')
      ! assuming not open, open ready to append past end of file

      ! get number of bytes in file plus one
      inquire(unit=igetunit,pos=nchars)
      ! opened for append, so subtract one to get current length
      nchars=nchars-1
      if(nchars.le.0)call stderr('empty file '//filename(:len_trim
(filename)))
      if(allocated(text))deallocate(text)
      ! make enough storage to hold file
      allocate ( text(nchars) )
      rewind(igetunit)
      ! input file -> text
      read(igetunit,iostat=ios) text
      if(ios.ne.0)then
         call stderr(' bad read of '//filename(:len_trim(filename)))
      endif
      close(igetunit)
      return
   end subroutine juslurp
end program rev_file
!-------------------------------------------------------------------------- -----
! how to make stdin and stdout and stderr stream files  ???
! how to tell how many units can be open and what unit numbers are
OK ???
!-------------------------------------------------------------------------- -----
   subroutine stderr(message)
   ! access computing environment
   USE ISO_FORTRAN_ENV, ONLY : ERROR_UNIT,INPUT_UNIT,OUTPUT_UNIT
   implicit none
   character(len=*) :: message
   write(ERROR_UNIT,'(a)')'*E-R-R-O-R:'//message
   return
   end
!-------------------------------------------------------------------------- -----
!
! I had hoped that if I closed the files assigned by ISO_FORTRAN_ENV
! to INPUT_UNIT, OUTPUT_UNIT, and ERROR_UNIT; and then opened them as
! non-scratch files but gave them a null name that they would open
assigned
! to the "stdin, stdout, stderr" files; or that if I did an OPEN on
the open
! pre-assigned files with ACCESS="STREAM" they would allow STREAM I/O
and
! so on but nothing worked. Is it an actual (and intentional?)
limitation
! of Fortran 2003 to not be able to use stream I/O on the "std*" files
or
! did I miss something? I have a lot of "filter" programs that do
stream
! I/O on stdin and stdout that I can at least change to use
ISO_C_BINDING
! and C calls instead of the hodge-podge of solutions I have now; but
until
! I tried it I has assumed that the 2003 Fortran stream I/O features
would
! allow me to write a stream-based "filter" program ??
!
! I really don't want to hear someone complain about Fortran lacking
portable
! stream I/O features again!! Any answers?
!
! Actually, an interesting exercise would be to see how many
extensions
! found at
!    http://gcc.gnu.org/onlinedocs/gcc-4.2.4/gfortran/FTELL.html
!
! get be replaced  with standard-conforming Fortran 2003 itself or
it's
! ISO_C_BINDING interface to C. Anyone have any Fortran students that
need
! a homework assignment? The result might make a useful library.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Arjen Markus  
View profile  
 More options Jun 26 2009, 4:54 am
Newsgroups: comp.lang.fortran
From: Arjen Markus <arjen.mar...@wldelft.nl>
Date: Fri, 26 Jun 2009 01:54:49 -0700 (PDT)
Local: Fri, Jun 26 2009 4:54 am
Subject: Re: STREAM I/O questions
On 26 jun, 10:13, John <urbanj...@comcast.net> wrote:

Have you tried using non-advancing I/O instead on stdin?

(I tried the re-opening trick myself, but that led to seek errors ...
Then later I thought it might be possible to achieve what you want
using ADVANCE='NO'.)

Regards,

Arjen


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Arjen Markus  
View profile  
 More options Jun 26 2009, 6:13 am
Newsgroups: comp.lang.fortran
From: Arjen Markus <arjen.mar...@wldelft.nl>
Date: Fri, 26 Jun 2009 03:13:45 -0700 (PDT)
Local: Fri, Jun 26 2009 6:13 am
Subject: Re: STREAM I/O questions
On 26 jun, 10:54, Arjen Markus <arjen.mar...@wldelft.nl> wrote:

Here is a "simple" example:

! filter.f90 --
!     Use stdin as a filter ...
!
program filter
    character(len=20) :: string
    integer           :: ierr
    integer           :: count
    integer           :: line
    logical           :: add_line

!   open( 5, access = 'stream', form = 'formatted', action = 'read' )
    line = 1
    add_line = .true.
    do
        read( 5, '(a)', advance = 'no', iostat = ierr, size = count )
string
        if ( ierr == -1 ) exit
        if ( ierr /= -2 ) then
            if ( add_line ) then
                add_line = .false.
                write( *, '(i5,2a)', advance = 'no' ) &
                    line, ' >', string(1:count)
            else
                write( *, '(a)', advance = 'no' ) &
                    string(1:count)
            endif
        else
            if ( add_line ) then
                add_line = .false.
                write( *, '(i5,3a)', advance = 'yes' ) &
                    line, ' >', string(1:count), '<'
            else
                write( *, '(2a)', advance = 'yes' ) string(1:count),
'<'
            endif
            line = line + 1
            add_line = .true.
        endif
    enddo
end program filter

Use it for instance like this:

cat filter.f90 |filter

Regards,

Arjen


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Richard Maine  
View profile  
 More options Jun 26 2009, 12:27 pm
Newsgroups: comp.lang.fortran
From: nos...@see.signature (Richard Maine)
Date: Fri, 26 Jun 2009 09:27:41 -0700
Local: Fri, Jun 26 2009 12:27 pm
Subject: Re: STREAM I/O questions

John <urbanj...@comcast.net> wrote:
> ! But I can't figure out a standard method of making the files pre-
> assigned ! to standard input and standard output (and stderr and other
> pre- assigned ! files too, I suppose) use stream I/O.

There isn't a guaranteed way. It is compiler- and system-dependent
whether you can do anything like that to standard input and output.
Might work, or might not depending on the compiler.

In principle, it is equally compiler- and system-dependent what you can
do to any file. It is just that standard input/output are more likely
than most other "random" files to have limitations. In general, I advise
against trying to reopen standard input/output.

As Arjen notes, you can use nonadvancing I/O to get some simillar
effects. It won't do all of the same things, but then some of the things
that you can't do with nonadvancing I/O are some of the things likely to
be problematic on standard input and output anyway. For example, it is
reasonably common for standard input/output to be connected to files
that cannot be positioned.

> ! how to tell how many units can be open and what unit numbers are
> OK ???

For a general answer to that question, see the INQUIRE statement. It is
fairly common to have a short routine that loops through candidate unit
numbers to find one that is vaid and unused. In practice, I find it
pretty safe today to assume that unit numbers 11 through 99 are valid. I
avoid single-digit unit numbers as they are often used for special
syste-dependent purposes, and 99 is the highest valid unit number on
some compilers (though it seems that most compilers today allow higher
ones).

The f2008 draft (last time I checked) provides a standardized way to get
an unused unit number, with the additional advantage that it gives you
one that is also guaranteed not to be used by anything else in the
future (something you can't otherwise guarantee). That makes it a bit
more like most other current languages, where you don't have to worry
about selecting a number, but just open a file and let the system assign
a suitable "handle". In my opinion, the use of numbers as unit handles
is an undesirable holdover from older days, but the proposed new feature
at least ameliorates the problems.

None of this will tell you, however, things like whether you can
successfully reopen standard input/output. It isn't specific to stream
I/O.

--
Richard Maine                    | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle           |  -- Mark Twain


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
glen herrmannsfeldt  
View profile  
 More options Jun 26 2009, 1:23 pm
Newsgroups: comp.lang.fortran
From: glen herrmannsfeldt <g...@ugcs.caltech.edu>
Date: Fri, 26 Jun 2009 17:23:39 +0000 (UTC)
Local: Fri, Jun 26 2009 1:23 pm
Subject: Re: STREAM I/O questions
John <urbanj...@comcast.net> wrote:

(snip)

< ! But I can't figure out a standard method of making the
< ! files pre-assigned to standard input and standard output
< ! (and stderr and other pre-assigned files too, I suppose) use
< ! stream I/O.

C has the freopen() function, similar to fopen(), except that
it closes an existing stream and opens the new file on the
same stream.  The usual use is for opening a new file as
stdin, stdout, or stderr.  

As far as I know, there is no similar operation in Fortran.

-- glen


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
John  
View profile  
 More options Jun 26 2009, 6:49 pm
Newsgroups: comp.lang.fortran
From: John <urbanj...@comcast.net>
Date: Fri, 26 Jun 2009 15:49:52 -0700 (PDT)
Local: Fri, Jun 26 2009 6:49 pm
Subject: Re: STREAM I/O questions
On Jun 26, 1:23 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

Thanks to everyone for the replies. When I don't have to categorize my
open files
I do use a routine that finds an unused number already( I added it to
http://fortranwiki.org/fortran/show/notopen); but I often find I need
to maintain a table with a text "tag" so I can scan for related files
(find all input files currently open, ...) so I find I usually use it
for files opened and closed in the same routine ( a help file, a
configuration file, ...). I had seen the f2008
NEWUNIT= put no compiler I tried seem to impliment it yet; I guess
that means if I open all my files that way in the future I don't need
to know the upper limit allowed
(until I hit the limit, I guess). I THINK the f1977 standard
used to say the guaranteed range was 1 to 99; I could
not find anything in the f2008 standard that mentioned any guaranteed
minimum range. freread(3c)
is interesting; somehow I missed that (and I've used
C a decent amount); I guess I am dissapointed that I
still cannot do (in a portable way) what I can do with the common
Fortran stream I/O extensions (ftell,fseek,fputc,fgetc,..). The
example using non-advancing I/O is something I'll keep; but that's
what
I was hoping to become free of ( using non-standard
extensions, calling C routines, not-so-simple uses of
non-advancing I/O and direct access files ) when I
want to make "binary" filters. Everything seems to work just fine
except with pre-connected units; but
I want to do binary streams too often to switch to the newer
ACCESS="STREAM" methods. I could already handle clear text files as
filters with f1977 for the
most part; it's the binary files or times that I want
to hold a text file in memory as a stream that I'd like to do in a
standard way.  Thanks again;
John S. Urban

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Richard Maine  
View profile  
 More options Jun 26 2009, 8:22 pm
Newsgroups: comp.lang.fortran
From: nos...@see.signature (Richard Maine)
Date: Fri, 26 Jun 2009 17:22:16 -0700
Local: Fri, Jun 26 2009 8:22 pm
Subject: Re: STREAM I/O questions
John <urbanj...@comcast.net> wrote:

[about valid unit numbers]

> I THINK the f1977 standard
> used to say the guaranteed range was 1 to 99;

No, it did not. No version of the Fortran standard has ever guaranteed
any particular range. And there were f77 compilers that didn't allow
that large a range, though that was a fairly common choice.

--
Richard Maine                    | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle           |  -- Mark Twain


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jfh  
View profile  
 More options Jun 29 2009, 6:08 pm
Newsgroups: comp.lang.fortran
From: jfh <john.har...@vuw.ac.nz>
Date: Mon, 29 Jun 2009 15:08:40 -0700 (PDT)
Local: Mon, Jun 29 2009 6:08 pm
Subject: Re: STREAM I/O questions
On Jun 27, 12:22 pm, nos...@see.signature (Richard Maine) wrote:

> John <urbanj...@comcast.net> wrote:

> [about valid unit numbers]

> > I THINK the f1977 standard
> > used to say the guaranteed range was 1 to 99;

> No, it did not. No version of the Fortran standard has ever guaranteed
> any particular range. And there were f77 compilers that didn't allow
> that large a range, though that was a fairly common choice.

> --
> Richard Maine                    | Good judgment comes from experience;
> email: last name at domain . net | experience comes from bad judgment.
> domain: summertriangle           |  -- Mark Twain

A problem with unit numbers that hit me 30 or so years ago was that a
certain commercial graphics package of Fortran subroutines used an
assortment of undocumented unit numbers for its own purposes, and I
had various problems if I tried to write to or read from one of those
units. The source code was not available. My workaround was to write a
test program to INQUIRE of each unit number 0-99 whether it was
currently open, before and after each subroutine call from the
package. (I didn't strike a case where a unit was opened and closed
during one package subroutine call.) Later, my university stopped
paying for that package, and PGPLOT became available. I still use
that.

John Harper


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ron Shepard  
View profile  
 More options Jun 29 2009, 8:42 pm
Newsgroups: comp.lang.fortran
From: Ron Shepard <ron-shep...@NOSPAM.comcast.net>
Date: Mon, 29 Jun 2009 19:42:02 -0500
Local: Mon, Jun 29 2009 8:42 pm
Subject: Re: STREAM I/O questions
In article
<01a9e5aa-5d2e-4576-9cfb-e83edbc2e...@x5g2000yqk.googlegroups.com>,

 jfh <john.har...@vuw.ac.nz> wrote:
> A problem with unit numbers that hit me 30 or so years ago was that a
> certain commercial graphics package of Fortran subroutines used an
> assortment of undocumented unit numbers for its own purposes, and I
> had various problems if I tried to write to or read from one of those
> units. The source code was not available. My workaround was to write a
> test program to INQUIRE of each unit number 0-99 whether it was
> currently open, before and after each subroutine call from the
> package.

I think a lot of software did this 30 years ago back before
open/close/inquire statements were available using preconnected
units and/or some kind of JCL incantation.  Open statements were
available on, for example, some of the DEC compilers and operating
systems before f77, but not on very many machines made by many other
vendors.  F77 fixed this, of course, but that would not really be
popular until the mid 80's, and even then often along with the older
version of the compiler that supported only the preconnected units.  
Most software libraries I used at least documented which file unit
numbers they used, although some of them kept the filenames
undocumented (or used random character strings that changed from run
to run).

$.02 -Ron Shepard


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
glen herrmannsfeldt  
View profile  
 More options Jun 29 2009, 11:26 pm
Newsgroups: comp.lang.fortran
From: glen herrmannsfeldt <g...@ugcs.caltech.edu>
Date: Tue, 30 Jun 2009 03:26:22 +0000 (UTC)
Local: Mon, Jun 29 2009 11:26 pm
Subject: Re: STREAM I/O questions

Ron Shepard <ron-shep...@nospam.comcast.net> wrote:
< jfh wrote:

<> A problem with unit numbers that hit me 30 or so years ago was that a
<> certain commercial graphics package of Fortran subroutines used an
<> assortment of undocumented unit numbers for its own purposes,
(snip)

< I think a lot of software did this 30 years ago back before
< open/close/inquire statements were available using preconnected
< units and/or some kind of JCL incantation.  

The DEC compilers would create a file named after the unit,
like FOR001.DAT

For IBM, you needed a JCL DD statement for each unit.
If closed source software used a unit, it would have to
be documented such that the appropriate DD statement would
be supplied.  The system cataloged procedures normally
supplied DD statements for 5, (SYSIN), 6 (SYSOUT=A, line printer),
and 7 (SYSOUT=B, card punch).  The number of available units
is a sysgen option, likely more on larger machines.

< Open statements were
< available on, for example, some of the DEC compilers and operating
< systems before f77, but not on very many machines made by many other
< vendors.  F77 fixed this, of course, but that would not really be
< popular until the mid 80's, and even then often along with the older
< version of the compiler that supported only the preconnected units.  

(snip)

-- glen


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »