File already open ERROR 3

 

Error Number: 3
Error Message: File already open

Description: The file you are attempting to open is already open. If you are USEing a database file, the file may be open in another work area.

  1. Check version
  2. SET EXCLUSIVE OFF
  3. USE <filename> AGAIN
  4. QUERY - QBE
  5. SET INDEX TO
  6. APPEND FROM <filename>
  7. Corruption
  8. Configuration
  9. Recursive calls
  10. CLOSE files properly
  11. FOPEN()
  12. Check for pathing errors
  13. "File already open", after editing a .prg, and trying to recompile
  14. Other potential causes of 'file already open'
  15. Further debugging

1) Check version
If you are receiving the error message "File already open", proceed to the dot prompt and issue the command,

? VERSION(0) 

or create a two-line .PRG with a "WAIT" as the second line to test dBASE IV Runtime applications.

If the string that is returned indicates you are using dBASE IV v1.1 or dBASE IV v1.5 build "xx67" (the original release of 1.5), or "xx69" (the first maintenance release) you are running up against a known problem.

The error 'File already open' has been found to be generated on 486/50mhz or higher machines (and on some fast 486/33's) with commands that effect the index, such as,

SET ORDER TO 
INDEX ON 
PACK etc. 

This problem is due to a change in the hardware you are now using. To get the extra boost in clock speed on CPUs 50Mhz or faster, a change was made in how the clock tick was handled. Unfortunately, dBASE IV was using this clock tick to manage its internal file handles. Changing the clock tick broke this method. dBASE ends up trying to open several temporary files with the same names and the "file already open" error is triggered.

dBASE IV v1.1 was not certified to run at this speed, since there was no such thing at the time it shipped. For v1.5 Borland has a maintenance release, dBASE IV v1.5 xx71, that corrects for this error. The xx71 build also include the fixes in the xx69 build. To obtain maintenance releases or upgrades contact Customer Service here on Compuserve, entering GO BORCS, or call (800) 331-0877.

Short Term Solution: Besides upgrading (truly the best solution) the only POSSIBLE solutions are to

(A) Slow down your machine:

- Disable caching
For example for SMARTDRV to turn write caching on and off, appended + or - to the drive letter.

SMARTDRV C+ && turn it on 
SMARTDRV C- && turn it off 

- Turn off "Turbo" mode.
- SET AUTOSAVE ON in your dBASE code.
- If dBASE temporary files are set to a ram drive

SET DBTMP=<ramdrive> 

Try setting this to a slower, physical drive. - Run from a network drive instead of from a local drive.

When the xx71 or above is received and installed the above should not be necessary.

(B) While the xx71 maintenance release is the best solution for most folks with v1.5 problems and fast machines there is a NON OFFICIAL patch uploaded by a user to correct the speed problem for users who are, for whatever reason, permanently or temporarily trapped with legacy applications that must run under DOS dBASE IV v1.1 or 1.5xx67 or 1.5xx69.

Lib: 1 IDXFIX.ZIP/Bin Bytes: 5822

Title : IDXFIX v1.0 INDEXing/PACK fixer
Keywords: INDEX INDEXING PACK PATCH BUG FIX IDXFIX

Fixes a known anomaly in some versions of dBASE IV v1.1 and 1.5 which causes an error during INDEX, PACK and REINDEX operations. Free yourself from the cursed "File is already in use" error message. Uploaded by the author, this is FreeWare from Barry Brevik.

-----------------------------------

2) SET EXCLUSIVE OFF

If NETWORK() returns .T., and either user A or B (or both) have EXCLUSIVE set to ON, the error message "File already open" will occur when the second user attempts to access the database.

WORKAROUND: Insert EXCLUSIVE=OFF in CONFIG.DB or use SET EXCLUSIVE OFF in program or from within dBASE _BEFORE_ opening the file. If NETWORK() returns .T. and both user A and B have EXCLUSIVE set to OFF, then normal file sharing, and file and record-locking should happen.

-----------------------------------

3) USE <filename> AGAIN

In dBASE IV v1.5, you can USE a database on a local drive AGAIN, irrespective of your EXCLUSIVE setting. However, you can not USE a database AGAIN on a network drive with EXCLUSIVE SET ON. For example:

?NETWORK() 
.T. 
SET EXCLUSIVE ON 
USE temp IN 1 USE temp AGAIN IN 2 
* ERROR file already open 

In dBASE IV 2.0 ( and dBASE 5 ), the key thing to remember is the LOCALSHARE setting. When LOCALSHARE is set OFF, dBASE IV 2.0, WORKS EXACTLY LIKE dBASE IV 1.5. In dBASE IV 2.0, by default, LOCALSHARE is ON. If SHARE is loaded, ?NETWORK() will return .T. and you cannot USE a database AGAIN, with EXCLUSIVE ON, no matter where the database is. For more information about ?NETWORK()=.T. and LOCALSHARE see Lib 10:

QID.FAQ - Id() session number - multi-tasking - LOCALSHARE

This USE AGAIN problem is "as designed". If exclusive mode is on then no one else on the network can open the file a second time ( the first being the one you just opened ) - if you try and use the AGAIN clause then you are just like another user and as such you will not be able to open the file.

The one main problem you may encounter with this, is this removes any possibility of doing a self-join with a query that creates an index on a network. To do a self join you need to USE...AGAIN. A temporary file may provide a workaround in this case.

-----------------------------------

4) QUERY - QBE

If you're using queries be aware that AGAIN will be generated automatically by the query if your doing a self-join or using a file more than once. See previous section USE <filename> AGAIN.

-----------------------------------

5) SET INDEX TO

When two files are open in two work areas, and each has an associated .MDX file, issuing SET INDEX TO <filename>.MDX where <filename> is the name of the file open in the unselected work area, will result in the error, "File already open". This is as expected since the production .MDX is open in the other work area.

-----------------------------------

6) APPEND FROM <filename>

You cannot APPEND FROM an open .dbf file. If you try to you recieve the error "File already open"

-----------------------------------

7) Corruption

Does the problem only happen with a particular database? Make sure this database is not corrupted.

  • Download,
    Lib: 6 DBFCLN.EXE - Dbfclean utility
    Lib: 6 DBTCHK.EXE - Dbtcheck utility
  • Run CHKDSK or SCANDISK and correct any disk errors.
  • Run the DBFCLEAN/DBTCHECK utilities.
  • Then in dBASE delete the MDX file and rebuild the tags.
    USE <filename>
    LIST STATUS TO PRINT
       && To get a hard copy of index and expressions
       && if you don't know this information.
    CLOSE ALL
    !DEL <filename>.MDX
    USE <filename> && choose PROCEED from error box
    INDEX ON ... TAG ... && ETC.

See Library 10: QCRPT.FAQ for more on corruption.

-----------------------------------

8) Configuration

Does the problem happen with a clean boot?

*- CONFIG.SYS *- AUTOEXEC.BAT
FILES=99 PATH=c:\dbase
BUFFERS=15 PROMPT $P$G
*** and only other _essential_ files such as disk drivers and compression utilities. If on a network, first test locally with no network connection.

This will rule out potential problems like caches, FASTOPEN, APPEND, etc. To rule out hardware problems test whether the problem happens on another workstation or computer.

-----------------------------------

9) Recursive calls

Does the problem seem to only happen within a program and NOT at the dot prompt or command window? If so the problem may be with the program code. Make sure your programs aren't calling themselves recursively. This can be the result of issuing a DO statement to go back to a previous procedure, instead of issuing RETURN. For example:

* prg_AA.PRG 
DO prg_BB 
RETURN 
* prg_BB.PRG 
DO prg_CC 
RETURN 
* prg_CC.PRG 
DO prg_AA 
RETURN 

Program AA calls BB, BB calls CC, and CC calls back to AA..., each program will occupy a file handle. The programs keep getting pushed on top of stack waiting to be popped off. The stack will eventually be filled up, and the operating system will run out of file handles. You will then see one of these messages depending what the application does:

"Too many files are open"
"File already open"
"Insufficient memory"
"Procedure nested too deep"
"Internal: Virtual Stack Overflow"

If a DO command is used in this manner, it is termed recursive programming. This involves a circle of programs or menus instead of a chain or hierarchy. In the above example, program AA calls program BB with the DO command. Program BB calls CC in a similar manner. Up to this point, there is a proper hierarchical chain of programs: AA-BB-CC. If program CC then calls AA with a DO command, a full circle would have been completed: AA-BB-CC-AA. This causes problems in dBASE as each opening of a module in this way uses a file handle. Only the file handle for the latest opened instance of a given module name can be released, other instances become irretrievably lost and the limited number of available file handled is quickly expended.

In this chain of programs, AA-BB-CC, module CC would ordinarily have a RETURN command at the point where its processing is considered complete. This automatically returns control to BB, at the first command line after the command line DO CC. Similarly, when a RETURN command in BB is encountered, control returns to AA.

* prg_AA.PRG 
DO prg_BB 
RETURN 
* prg_BB.PRG 
DO prg_CC 
RETURN 
* prg_CC.PRG * 
... code ... 
RETURN 

There is one exception to this, and that is the need to go directly from CC back to AA, but closing all intermediate open modules in the process. This can be accomplished with the RETURN TO MASTER command (in CC). This would have the same apparent effect as DO AA (invoked in CC), but does go back through each open intermediate module in the hierarchy, closing each, until the topmost level is reached.

* prg_AA.PRG 
DO prg_BB 
RETURN 
* prg_BB.PRG 
DO prg_CC 
RETURN 
* prg_CC.PRG * 
... code ... 
RETURN TO MASTER 

A good way to spot recursive calling is to use a program code documentor such as SNAP.

LIB 14: SNP502.ZIP
Title : Snap! Version 5.02 - Program Documentor for xBase

-----------------------------------

10) CLOSE files properly

A problem that is related to the above RECURSIVE CALLS, which is not common but might crop up; If you quit to DOS from a program without properly closing the files, and then run dBASE again, you may sometimes by unable run the program without resetting the computer. You'll know for sure if you get "Too many files open" or some similar message, such as:

File already open Insufficient memory Internal Stack overflow Procedures nested too deep

This happens because the internal stack is filled with previously called routines in the program that are never removed from the stack. CLOSE ALL and CLEAR ALL do not seem to solve this problem.

The solution is to reboot, then check the program out to make sure it closes files properly. This includes CLOSEing files and making sure you do not QUIT from a program unless you are at the calling level of the program.

-----------------------------------

11) FOPEN()

On a network volume, a file can only be FOPEN()'ed once.

-----------------------------------

12) Check for pathing errors

Where is SET PATH TO? If you have more than one copy of the file things can go wrong. Are all your files (program and database files) in one directory or several? Does is work if they are all in the same location? Does it work if you,

  • Use full path name AND file name?
    USE c:\dbase\data\<filename>.dbf
  • Reduce DOS PATH to just the current directory.
    SET PATH TO x:\dirname
  • Set the default directory with,
    DIRECTORY = x:\dirname
    In CONFIG.DB, or in your program,
    SET DIRECTORY TO x:\dirname

-----------------------------------

13) "File already open", after editing a .prg, and trying to recompile

If using an external editor: Make sure you have SET DEVELOPMENT ON. Also note, dBASE may not be able to recognize the update of a file if the editor has the file handle opened. Unless the editor release the file, no recompile is possible. If you close your editor after the edit, then SET DEVELOPMENT ON should work.

One way to avoid problems with the file remaining open is to start the editor by creating a new file, ex: TEST.$$$ Read in the file you wish to edit. ex: anyfile.prg. Write out your changes to anyfile.prg. Now TEST.$$$ is still opened, but anyfile.prg is not. This should alleviate the necessity of doing a compile on the program.

If using SET PROCEDURE TO <filename>, SET LIBRARY TO <filename>: Make sure to close the procedure or library file before editing,

SET PROCEDURE TO 
SET LIBRARY TO 

* TO <nothing> closes.

-----------------------------------

14) Other potential causes of 'file already open'

- Issuing a SUSPEND without a CANCEL.
- Any abnormal termination that does not release the file properly.

-----------------------------------

15) Further debugging

a) If working in a network environment CONVERT your database(s).

USE <filename> 
CONVERT TO 24 

For more on CONVERT see Language Reference and Lib 10: QCNVRT.FAQ - Press space, record may have changed - CONVERT

b) SUSPEND at error or use the DEBUGGER to trap.

DEBUG method 1:

DEBUG <program) 
R <enter> - run until interrupted by error. 

DEBUG method 2:
Disable any ON ERROR routines by inserting
ON ERROR
before the problem code, or search for and comment out any ON ERROR routines in your code ( ON ERROR overrides SET TRAP ). Then

SET TRAP ON 
DO <program> 

This should kick you into the debugger on the line triggering the error.

Press "U" to SUSPEND and issue the following. What do they return?

?NETWORK() 
?SET("EXCLUSIVE") 
* Does USERS correctly show who 
* is currently logged in? 
LIST USERS 
* Does status show the file 
* anywhere else in use? 
LIST STATUS 
* If you close all files does 
* the problem also go away?
CLOSE ALL 
USE <filename> 

If this problem is happening intermittently, include an ON ERROR routine in you code, to store this information when the problems occurs. For example

ON ERROR DO err_proc WITH ;
   LINENO(),PROGRAM(),ERROR(),MESSAGE()
... code ... 
RETURN 
PROCEDURE err_proc 
PARAMETERS nLineno, cProgram, nError, cMessage 
CLEAR 
SET ALTERNATE TO errlog.txt 
* Use ADDITIVE with the above command if you wish
* to create a running log. The alternate file must
* first exist if you wish to use ADDITIVE. To do 
* this first create errlog.txt MODIFY COMMAND 
* errlog.txt. 
SET ALTERNATE ON 
? DATE() 
? TIME() 
?"VERSION: " 
??VERSION(0) 
?"LINENO:" 
??nLineno 
?"PROGRAM: " 
??cProgram 
?"ERROR #:" 
??nError 
?"ERROR MESSAGE: " 
??cMessage 
?"NETWORK: " 
??NETWORK() 
?"EXCLUSIVE: " 
?SET("EXCLUSIVE") 
LIST USERS 
LIST STATUS 
LIST MEMORY 
SET ALTERNATE OFF 
SET ALTERNATE TO 
* If running in dBASE and not in an EXE, include 
* the following for interactive debugging 
SET COLOR TO &cColor 
SET COLOR TO W+*/R 
?"SUSPEND see ERRLOG.TXT" 
SET COLOR TO &cColor 
SUSPEND 
* <- 
RETURN 

For an extensive error log routine see, ERRLOG.PRG -- Error Log -- useful for programmers when a system crashes -- creates a log file, and on a LAN can send a message to the programmer.

In the following freeware library of procedures and functions:
Lib 6:
LIB211.ZIP (dBASE IV, 1.5 or less)
LIB20?.ZIP (dBASE IV, 2.0) ** where ? is latest build.

Lib 7:
LIB50?.ZIP (dBASE 5.0) ** where ? is latest build.


[Home] [FAQ Index]