- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1) I'm well aware of the intrinsic inquire function which applies to a statement like:
inquire (file = "FileName.inp", exist=result)
But suppose I want to inquire about the existence of a Directory. Is there a counterpart statement for this? In some checking I've done, I haven't been able to find such.
2) Suppose we can find a way to determine the existence of some Directory. If for a statement like the above result = .true., then suppose we want to purge (delete) it from an earlier run (so it can be created anew). Is there a simple command to Remove this Directory?
In preliminary checking, I'm not sure I have seen a reliable command for this, especially one that isn't very dependent on the library one is using. FWIW, in my case, I'm using DFlib (not iFort).
In DOS, I could always do this very easily.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have to say (echoing FortranFan) that in my commercial applications which are windows based I would use windows sdk routines and standard Fortran only. Pumping out external commands such as I exampled I tend to use in 'for my own benefit only' quick bits of code as you can do a lot with very little code if you don't have all the potential pitfalls to secure against. Sticking a command that can kill entire directory trees without warning is a bit of a worrying one if you have not been ultra careful in its use.
Anyway, TommyCee, I'm glad you found a result suitable for your needs and learned a couple of things which it the main objective and benefit of participating in forums such as this. I learn useful things here all the time....
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
GETFILEINFOQQ can tell you if a file is a directory (a flag in the PERMIT field of the structure returned.) There is no Intel Fortran library routine to delete a directory, but the Windows API routine RemoveDirectory will do it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I appreciate what you say, Steve, but I'd really like to just see if a directory is present (and if so, delete it). As I say this, it now occurs to me that even if I can see if the directory exists, it may well be a problem deleting if it's filled w/ files. Any thoughts on that?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Using a command like this will definitely determine the existence of the Directory 'DIR':
INQUIRE (DIRECTORY='DIR', EXIST=LEXIST)
When 'DIR' is present, Lexist = .true.
The question now is:
If Lexist = .true., how best to wipe out 'DIR' ??
For Linux, I stumbled onto this gem:
rm -rf DIR
which supposedly will wipe out 'DIR' even it it's populated (w/ no prompts for each contained file). A F90 command like this that will work within IVF would be great.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The Windows API provides a ready solution for path status,
[fortran]
handl = FindFirstFile (pathname, fdata)
netpath_ok = (handl /= INVALID_HANDLE_VALUE)
IF (netpath_ok) THEN
nc = FindClose (handl) ! release system resources
ELSE
[/fortran]
where pathname is a (null-terminated) path, ie pathname = c:\somedir\subdir//CHAR(0)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Like I say - with
INQUIRE (DIRECTORY='DIR', EXIST=LEXIST)
I have a good way to verify if the "offending" directory is present.
I need to find an efficient way to KILL it (i.e., make it disappear) on the fly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can use DELDIRQQ or or the sdk function (http://msdn.microsoft.com/en-gb/library/windows/desktop/aa365488(v=vs.85).aspx) but niether work unless the dir is empty. You must delete the contents first.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A quick way would be to issue a command such as :
RD /S /Q "C:\Users\UserName\Desktop\Folder"
which deletes "folder" and all it contents without and prompts assuming you have permission and there are no locked files etc...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK app4619 - I appreciate your comments and here are mine:
DelDirQQ is a nonstarter if the "offending" directory is populated w/ files.
The other link SDK link leads to C++ routines which, while ideally suited to the task at hand, do not marry well w/ F90. (I didn't want to have to build a DLL.)
And your RD /S /Q "C:\Users\UserName\Desktop\Folder" appears to be a DOS command which is not (at least easily) executable in the F90 framework.
The most fruitful option was the one Steve put me onto w/ GetFileInfoQQ, which led me to a few other associated IFport functions. The only way to do this, and it's what I like to call a "sledge hammer" approach" is to change directories TO the offending directory, and then delete the files. In my case, if I am able to delete only 2 files, the main problem goes away b/c the other files will be overwritten by my code.
This first conjures the function ChangeDirQQ(TargetPath) - I'm using my own argument names. Since this code needs to be generic/robust, the pathway to the offending directory must be created within the context of the (any) user's machine. This conjures an associated function GetDriveDirQQ(WorkingDirPath). So here, once I get the Working Directory Path, I concatenate the other part of the path that involves a couple subdirectories and - voila - I finally get the full pathway to the "offending" directory. Success.
At this point, I need only one thing. Rather than a weapon to kill a directory, I need an F90 weapon to kill an existing (and of course unopened) file.
Any ideas on how to kill a sitting file on the fly?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
TommyCee wrote:
.. I need an F90 weapon to kill an existing (and of course unopened) file.
..
Why unopened?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Because it was (or may well have been) created in an earlier run of the program. It's just sitting there.
As sure as I didn't mention this, someone would have cone in with a complicated suggestion & code to close it or unattach it, etc.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The dos command is simple one liner e.g. below. You will need to build the string to send to the system command if you want it to be more general USE IFPORT INTEGER(4) I I = SYSTEM('RD /S /Q "C:\Users\UserName\Desktop\Folder"')
The "C command" in the sdk can be called direct from Fortran with a simple interface that is provided by "USE IFWIN".but as a pointed out and as you are aware it must be empty for that to work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
TommyCee wrote:
Because it was (or may well have been) created in an earlier run of the program. It's just sitting there.
As sure as I didn't mention this, someone would have cone in with a complicated suggestion & code to close it or unattach it, etc.
Well, you said, "I need an F90 weapon to kill an existing file" and I was wondering why you couldn't do something as follows:
... INTEGER :: Lun CHARACTER(LEN=:), ALLOCATABLE :: SomeFileName CHARACTER(LEN=2048) :: IO_ErrMsg !.. Arbitrarily long string LOGICAL :: FileExists INTEGER :: IO_Err ... !.. Specify the file name from whatever source you've SomeFileName = ... ... INQUIRE (FILE=SomeFileName, EXIST=FileExists, IOSTAT=IO_Err, IOMSG=IO_ErrMsg) IF (IO_Err == 0) THEN IF (FileExists) THEN OPEN (NEWUNIT=Lun, FILE=SomeFileName, ACTION='READWRITE', IOSTAT=IO_Err, IOMSG=IO_ErrMsg) IF (IO_Err == 0) THEN CLOSE(UNIT=Lun, STATUS='DELETE', IOSTAT=IO_Err, IOMSG=IO_ErrMsg) IF (IO_Err /= 0) !.. Do the needful; error description for delete failure in IO_ErrMsg string ... END IF ELSE !.. Do the needful; error description for file open failure in IO_ErrMsg string ... END IF END IF ELSE !.. Do the needful; error description for file inquire failure in IO_ErrMsg string ... END IF
All you would be doing with the above is open the file and if open is successful, then immediately close it with a 'DELETE' status.
Any specific reason why something as simple as this wouldn't work for you?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your clarification, app4619. As always, a little bit of code to give context is always a HUGE advantage. I learned something about executing a "DOS" command in within F90 code. I may well play w/ this to gain some familiarity.
To obviate the "directory must be empty" constraint, I have devised an algorithm to simply (or maybe not so simply) go to the target directory where I may delete the files of interest.
So, I need a command to delete a named file. Using your template, would something like this work?
USE IFPORT INTEGER(4) I I = SYSTEM('del FileName')
Or, I wonder if I might use something like this which includes the entire path and not have to Change Directories:
USE IFPORT INTEGER(4) I I = SYSTEM('del FullPath\FileName')
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
RD (RMDIR) does not require the directory to be empty with /S so the command shown above should do what you want.
Remember with invoking dos commands that you need a 'silent' mode. I.e. if the command asks 'are you sure?' that is a problem so you need a silent command option (if it exists) rm and del have /Q (Quiet mode).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
At long last, I think I'm ready to wrap up this thread. Thanks a lot for recent contributions by FortranFan & app4619.
In looking at the code FF presented, it looks like that would work but, if I may say so, involves 2 or 3 sledge hammers. <grin> But I appreciate it all the same ,,,
app4619's DOS command wrapped within a function call to SYSTEM turns out to be the perfect ticket! I had no idea I wielded such power at my fingertips all along ... <bigger grin>
I = SYSTEM('RD /S /Q "C:\Users\UserName\Desktop\Folder"')
will certainly do the trick, exactly as app4619 claimed. However, in my app, it's not robust in the sense that the pathway would have to be manually specified per machine [i.e., there is no (easy) way to "automatically" apply the results from GetDriveDirQQ(WorkingDirPath) ]
With this in mind, the ultimate robust way to do it is as I described in my earlier post, and then - once you're "looking" at the target directory - do this:
inquire (file = "OffendingFile.ext", exist=result) if (result) I = SYSTEM('del "OffendingFile.ext"')
In preliminary testing I've done w/ this, it seems to work like a top!
My takeaway is that harnessing the SYSTEM function call, I have access to very powerful DOS commands.
All of a sudden, I'm feeling like the Midas Man.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
TommyCee wrote:
...
In looking at the code FF presented, it looks like that would work but, if I may say so, involves 2 or 3 sledge hammers. ...
...
My takeaway is that harnessing the SYSTEM function call, I have access to very powerful DOS commands.
All of a sudden, I'm feeling like the Midas Man.
Not sure where you see any sledgehammer, let alone several!
Do note the code I presented is standard Fortran, so you get all the benefits of using standard code, particularly portability, if that is important to you.
Do keep in mind the function SYSTEM (or SYSTEMQQ) is a non-standard extension that can be constraining depending on how and where your code will be used. In addition, system calls such as this one need to be used with great caution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FF:
My only point was that my 2 lines of code does what your 20-odd lines of code does!
For coding, I apply the philosophy of Occam's Razor with the design goal:
simpler, smaller, lighter, fewer moving parts ===> results in the most robust application.
Your last point was most intriguing:
Do keep in mind the function SYSTEM (or SYSTEMQQ) is a non-standard extension that can be constraining depending on how and where your code will be used. In addition, system calls such as this one need to be used with great caution.
I was unaware of this caveat and will bee on the lookout for errant behavior. I appreciate the heads up, FF.
What I might really find useful (if there is such a thing) would be a short reference on tasks and their F90 syntax that can be accomplished using function SYSTEM. I have searched MSDN and haven't really seen anything. Maybe there's something elsewhere.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
TommyCee wrote:
..
My only point was that my 2 lines of code does what your 20-odd lines of code does!
...
Generally speaking, it isn't appropriate to compare number of lines of code unless it is prohibitively large in one scenario (which is not the case here).
Also, note most of the lines of code in my example are there to alert you to the fact that you need to consider navigating your program through a maze of potential error scenarios during any operations, particularly I/O and file processing. So you'll need to account for the same with the SYSTEM function call as well, but the sample code shown didn't have any of that. For example, what if the call fails or what if the file to be deleted is locked by some other process (so what happens to that other process if you were to brute-force the file delete step), etc. Once you take such things into consideration, it will no longer be a couple of lines of code. Alternately, if you were to ignore such things in the standard Fortran example, you can make do with a couple of lines too:
IF (FileExists) THEN OPEN (NEWUNIT=Lun, FILE=SomeFileName, ACTION='READWRITE') CLOSE (UNIT=Lun, STATUS='DELETE') END IF
But such an approach is not good programming practice, as you know.
TommyCee wrote:
..
What I might really find useful (if there is such a thing) would be a short reference on tasks and their F90 syntax that can be accomplished using function SYSTEM. I have searched MSDN and haven't really seen anything. Maybe there's something elsewhere.
...
SYSTEM function call is an Intel Fortran extension that is made available via IFPORT module. This option is very powerful, as you've realized, and it can do almost everything that is possible via a system command - hence it needs to be used with great caution. Look in Intel Fortran Help and Documentation for SYSTEM or SYSTEMQQ.
On the other hand, standard Fortran only allows a few systems programming options: Fortran 2003 and 2008 have added a few options that were not available previously such as getting command line arguments, environment variables, etc. You can review the books mentioned in Dr Fortran's blog at https://software.intel.com/en-us/blogs/2013/12/30/doctor-fortran-in-its-a-modern-fortran-world for more details.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan,
I appreciate all your caveats & admonitions and don't want to engage in an argument w/ you on this forum. I get your points. In my world, monitoring code behavior is an ongoing process. If extra lines of code (to create what I call Guardrails) become necessary, I will assuredly install them. But there's also the adage "If it ain't broke, don't fix it." What I have learned from this post I have incorporated into a subroutine. Though you wouldn't know it because I have not cluttered this post w/ all my code, your concern what if the file to be deleted is locked by some other process would be highly unlikely since the file was closed by the previous execution of the program. And as a practical matter, if (God forbid) the deletion failed to happen, it would not be the end of the world. In my particular system, removal of 2 files was mainly an added a convenience to the user since in the execution of my program in another mode, they would not be overwritten. To present more that I wanted to say, but to be more clear, if the program is run in one mode, 9 files would be written to several output directories. If the program is immediately run in "the other mode", only 7 different versions (of the 9) of the same files would be written. Hence, 7 of the 9 would be expected; 2 would be "left over" from the previous execution. Hence, the need for my deletion subroutine, which so far does a marvelous job.
I appreciate the link to Dr.Fortran's bibliography. I am familiar w/ some of the refs. he lists.
The closest thing I have found to what I seek is this:
and its companion:
Each of these links provides one tiny example showing actual syntax. What I would like is a page that shows many different application examples for command line syntax. That would be huge.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No worries..
Since the files in question are related to your own program, whose details will be known within your code, and on which there will be Fortran-specific file I/O operations (at least WRITE statements) anyway, it does seem sticking with standard Fortran, instead of using a system command, is a cleaner approach.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page