Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

File Already Open? 1

Status
Not open for further replies.

qbasicking

Programmer
Aug 19, 2001
628
US
I have been puling my hair out on this. I want to KILL a certain file, but when it reaches the command it gives me a "File Already Open" error. I have checked all of my files, every OPEN has a corresponding CLOSE.
Can anybody think of something else that will give me this error?
 
I suppose there are quite a few ways this could happen in code. The most obvious: you haven't actually closed the file. Say, you accidentally change the value of the variable that holds the file number (stranger things have happened), or you haven't actually closed each file number you included in your [tt]OPEN[/tt] statements.

For example....

DEFINT A-Z
' [tt]Set up a data record[/tt]
TYPE MyRecordType
MyRecord AS STRING * 255
END TYPE
DIM MyData(1) AS MyRecordType
' [tt]Open the file...[/tt]
fb = FREEFILE
OPEN "MyFile" FOR BINARY AS #fb
MyDataVariable$ = STRING$(255, "?")
' [tt]...and write some raw data to it.[/tt]
PUT #fb, 1, MyDataVariable$
' [tt]............................[/tt]
' [tt]....bunches of code here....[/tt]
' [tt]............................[/tt]
' [tt]............................[/tt]
' [tt]Then open the file for random access[/tt]
' [tt] so you can read the data into your UDT record.[/tt]
fr = FREEFILE
OPEN "MyFile" FOR RANDOM AS #fr LEN = LEN(MyData(1))
GET #fr, 1, MyData(1)
PRINT MyData(1).MyRecord
' [tt]You're finished with the file, so close it...[/tt]
CLOSE #fr
' [tt]You just want to make sure, so close it a few more times...[/tt]
CLOSE #fr
CLOSE #fr
CLOSE #fr
CLOSE #fr
' [tt]I hear somebody laughing out there.[/tt]
' [tt]I'm not being sarcastic,[/tt]
' [tt]just trying to make a point.[/tt]
' [tt]Now let's delete the file....[/tt]
KILL "MyFile"
' [tt]Hmmm... that doesn't work. The file is already open....[/tt]
' [tt]Didn't I just close it five times?[/tt]

I would suggest that you post some code so we can take a look at it... but that would probably be pointless. You will probably discover your error and correct it, forgetting all about your question.
vcb.gif

Do no harm.​
 
That couldn't happen, i don't use variables when I open the files, I use numbers
OPEN file.dat FOR BINARY AS #1
'code
CLOSE #1

I have painstakingly looked over the entir source, both by scrolling through it and using the search function, every OPEN has a CLOSE statement of the same number somewhere near it. And the SUB that KILLs the files can never be called in between them.
I also make sure that there is really a file to KILL, but opening it and closing again.
 
>> if you dont have any files that you actully *want* open at that point where the error is, then just say:

CLOSE

>> to be sure that all files are closed at that point. close without a corrisponding variable or number simply closes all open files regardless. something i do at the end of all my applications just to be sure i dont accidentaly leave a file open during development.
 
Have you tried using the RESET statement before the KILL?

It works sorta like CLOSE w/o a parameter, but I think it flushes and releases all file buffers and handles too. This is only good if you don't have to keep any other files open of course.

The same thing can happen in VB, even VB6. The main reason for the FreeFile() kludge in MS Basics is the way file handles are managed. You can open #1, write crap, close #1 and try to open #1 again and get "in use" errors. The #1 slot in the file handle table doesn't clear up immediately or something. In your case I think the file might still be "open" at some level even after a close.
 
I remember having this problem. There are many ways to fix this once you understand how it works. I am sure you will find the one that works best for you. The most common mistake is creating a loop or sub in which a file is opened and then the sub/loop exit-ed. The simplest way that should work is simply have a "security" close not only after the open command but before it too. Hope you get it...GLHF
 
I have decided to close all of the files that i had opened, it slows my program down, but I also makes it more stable
 
What exactly did you do?

From your original post, I thought you already had a CLOSE for every OPEN.

Did your fix seem to be a solid cure?
 
Before i was using CLOSE #.. Now I am just using CLOSe, without a file number
 
I don't recall the OS you're using but I do remember it had happened to me several times. I believe it was when I had purchased a new sys with 95 and the bios' hd had a write-back delay set. I initially used a SLEEP 4/5 to allow the cache to physically write to the drive--but eventually I was fed up and changed it to write-through.

You can try that Sleep 4 or 5 too. Another option is as follows:

place a BreakPoint at the KILL statment to stop execuition. When it stops, (since you claim it is a SUB) press ALT & C for the Call Stack. Then trace it backwards to confirm what dilettante said about exiting a SUB before the CLOSE statement was execuited.

Don't forget to ALT+D, activate HISTORY and use the SHIFT+F8 key to step backwards. I think it's limited to the last 15-20 statements execuited.

--MiggyD
 
dilettante,
thats not quite true about vb and freefile()
I almost always use Open...#1 ... Close
the only time I use Open #2 is when it is Absolutely nessisary to have 2 files open...
For example copying a file or translating

I suggest you not open more than 2 files at a time...
There is really no reason for this...
keep it simple... store your files in strings...
'(((VB5/6...)))
Function GetFile(File as string) as string
open File for append as #1
close
open "bla.bla" for input as #1
if eof(1) then close:kill File:beep:exit function
S$=""
do
line input #1, A$
S$=S$+A$+chr$(13)+chr$(10)
loop until eof(1)
close
GetFile = S$
end function

Good Luck,
-Cube-E (QB)
 
There's something I must be missing here, CubeE101. What you have done is the functional equivalent of:
[tt]
OPEN "bla.bla" FOR BINARY AS #1
S$=STRING$(LOF(1), 32)
GET #1, , S$
CLOSE #1
GetFile = S$
[/tt]
Were you using LINE INPUT to read the file, line by line, with hopes of placing the lines in an array? It might be more efficient to read the entire file into a single string and then loop through it, parsing the lines into array elements using INSTR and MID$.

Regarding the problem of insuring file close for hard-coded handles, I suspect that dilettante is correct. File numbers #1, #2, etc. do not equate, in any way, to the actual file handles maintained at the OS level. These are just sequential markers used, internally, by Qbasic to point to certain values in the OS file handle table.

While it is possible for Qbasic to get a bit confused, it is a near certainty that programmers will become confused. Since I don't want to delude myself by assuming that file #1 is the first file I opened, file #2 is the second file I opened, etc., I prefer to let the OS and QB take care of the sordid file-handling details. I do this by placing the next available open file handle in a variable and then refer to that variable every time I want to perform operations on that file. I don't want to open a file as #7 because I can open it several times as #7... multiple closes of #7 may fail to close it completely.

The generally accepted programming practice is to use FREEFILE to determine the next available file number. Mind you that this is not a "generally accepted" practice because a bunch of guys got together in a basement and decided to dream up some rules for the rest of us. It is "generally accepted" because it works consistently, the way file handling was intended to work.
vcn.gif

Do no harm.​
 
Alt255,
I don't Know what I was thinking... It was probably late... It's 4:30 AM right now (here)...

The Point I was trying to get across was that the hard coded handles #1, #2... are ReUseable so you can
Open ... #1 'Open a file
Close ... #1 'Close the file
Open ... #1 'Open a different File
Close ... #1 'Close the other file


as opposed to...
Open ... #1 'Open a file
Close ... #1 'Close the file
Open ... #2 'Open a different File
Close ... #2 'Close the other file


As for softcoded files...
If you have a program that, for say, has recursive functions, or some other reason for on the fly open files to where there can be an unknown # of Open Files at once, Then the freefile is the best option...

As for the reading a file into a string...
I think I got mixed up and was thinking that I was in the VB5/6 forum (oops...) that is the best way (that I have found) to read files and display them properly in a textbox... (sorry... a bit out of place here) in QB I would most likely use:
Open ... Binary as #1
Get #1...
Close

like you said...
Though I haven't tried it in VB yet...
Thanks for bringing this to my attention Sometimes... the BASIC things in life are the best...
cheers.gif

or at least the most fun ;-)
-Josh Stribling
 
Here is something you may have done.

FOR LOOPER = 1 to 5
OPEN "SOMETHING.DAT" FOR OUTPUT AS #1
PRINT #1, LOOPER
NEXT LOOPER
CLOSE #1
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top