Re: fortran code for 'cp' / subroutine file_copy
- From: nospam@xxxxxxxxxxxxx (Richard E Maine)
- Date: Fri, 31 Mar 2006 08:30:54 -0800
Carsten Lemmen <c.lemmen@xxxxxxxxxxxxx> wrote:
I would like to issue a copy operation from within my Fortran code. I
have been using the system intrinsic, however, some compilers do not
know about this intrinsic.
While trying to implement my file_copy subroutine, I got stuck at the
open and read statements for an arbitrary (binary or ascii) file to
copy. both gfortran and f90 (nag) give different runtime errors. Any
recommendations, has anyone else implemented this?
There simply is not a 100% portable way. Some ways have better
portability than others, but none are 100%. Whatever you do, the most
important thing is to isolate it and document it as a system dependence
so as to facilitate porting when it needs it. As long as you
sufficiently isolate it, yuo can use completely different methods on
different systems. Yes, that means you have to mantain multiple versions
of the code and have a way to select among them, but that doesn't have
to be a horribly big deal. I've got a module that I call sysdep_io,
because I/O is one place where there are several system-dependent things
that I find myself regularly needing.
Here's my "generic" version, cut&pasted right from the file. My
"generic" version of the sysdep I/O stuff is intended to at least
compile and run sensibly on pretty much anything, giving up
functionality for the sake of portability. Some of my apps don't
strictly need all of the functionality, so sometimes I can get by with
things like:
subroutine copy_file (source_name, dest_name, error)
!-- Copy a file.
!-- Currently no checks for overwriting.
!-- There is no good generic way to do this,
!-- so this version always reports an error.
!-- 20 Jun 96, Richard Maine.
!-------------------- interface.
character*(*), intent(in) :: source_name
character*(*), intent(in) :: dest_name
logical, intent(out), optional :: error
!-------------------- executable code.
call write_error_msg('Copy_file not implemented.')
if (present(error)) error = .true.
end subroutine copy_file
Somewhat repetitive with things said by Arjen, Meek, and Joost, but I'll
try to summarize, and add a few small bits.
I'll agree with Chris and argue for the system() as a good option in
many cases. It's what I use most of the time (in the versions of the
above that do something more useful than declaring an error). Not only
do you have to tweak the exact form (and name) of the system() call for
different systems, but of course, the syntax of a copy command varies
also (copy vs cp, etc.). Even with those issues, I still think it is one
of the better options.
You can sometimes use some variant of direct access, as suggested by
Arjen, but it would take a pretty long post to cover all of the details
of all of the "issues" that can come up. It can work, but beware of the
issues, which I'm not going to take the time to cover in detail here.
(End-of-file detection is one - and no, err= is not a 100% solution to
that. Record size is another. Formatted vs unformatted is another.
Compiler-dependent headers is another.)
Most of the issues relating to direct access can be avoided by using
stream I/O. It is probably my #2 recomendation (a system() call is #1).
Until f2003, stream I/O is compiler-dependent and the exact spelling
varies, but most compilers have the functionality one way or another. So
yes, you still have to worry about porting among compilers, but it is
usually doable without too much pain. Furthermore, F2003 standardizes a
spelling of stream I/O, so you have good assurance that future compilers
will provide the capability and that the portability issues of this
approach will get beter instead of worse.
If you really want 100% portability, you'll start running into issues
such as meta-data. Some systems have record type information and other
stuff that isn't in the "data" part of the file. Thus even stream I/O
won't be able to get it. This used to be the norm; it is now less
common, but plenty of such systems still exist. And then there are
things like Mac resource forks as another example of meta-data. You can
copy such meta-data with an appropriate system call, but you aren't
likely to be able to do it directly in Fortran (or any other language)
without having some *VERY* system-specific code.
Oh. Just for completeness. I should be obvious but... if the files to be
copied happen to be in specific formats that you know, other
possibilities open up. Sometimes you know that the files are in one of n
formats, but you just don't know which one. You might be able to do some
tests to deduce which one is right (if only trial&error). Depends on the
application whether this makes any sense at all, but it is at least one
of the options to put on the plate.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain| experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
.
- References:
- fortran code for 'cp' / subroutine file_copy
- From: Carsten Lemmen
- fortran code for 'cp' / subroutine file_copy
- Prev by Date: Re: Automatic allocation of an available file unit
- Next by Date: Re: fortran code for 'cp' / subroutine file_copy
- Previous by thread: Re: fortran code for 'cp' / subroutine file_copy
- Index(es):
Relevant Pages
|