I have a simple problem that I don’t know how to fix.
Sometimes when my code goes wrong some files don’t get closed properly.
So when on the next try I want to open them, I get an error message.
I’ve tried this code but it does not work. My only option is to close AppleScript and reopen.
try
set outputFile to open for access file ("Nico C300:Users:nlavabre:Documents:Projects:Test XML:" & outputFileName) with write permission
on error
close access outputFile
set outputFile to open for access file ("Macintosh HD:Users:nlavabre:Documents:Projects:Test XML:" & outputFileName) with write permission
end try
I guess there’s a smart way out of that but I don’t know it nor I found it some place.
set outputFilePath to "Nico C300:Users:nlavabre:Documents:Projects:Test XML:" & outputFileName
try
set outputFilePointer to open for access file outputFilePath with write permission
-- do something
close access outputFilePointer
on error
try
close access file outputFilePath
end try
end try
set theFile to (choose file) as string
set NrOfAttempts to 0
set myString to stringFromFile(theFile)
repeat until myString is not null
set NrOfAttempts to NrOfAttempts + 1
if NrOfAttempts > 10 then
exit repeat
else
delay 0.5
end if
set myString to stringFromFile(theFile)
end repeat
return myString
on stringFromFile(theFile)
try
set fd to open for access file theFile
set theContent to read fd as string
close access fd
on error
close access file theFile
set theContent to null
end try
return theContent
end stringFromFile
When a error occurred the code will try to redo the action till it tried it ten times. Then it will quit and it should throw an error. Increase or decrease the delay or attempts to your wishes. I use it when waiting for a file and remember that a file can be opened by the system once with write flag and hundreds with a read flag so use the write flag only when you need it.
I have only need to be able to reuse a file that has not been closed properly during my previous test. I’m not ‘waiting’ for any file although that could be useful some time.
Stefan, shall I really ‘do something’ there or may I write it this way:
set outputFilePath to "Nico C300:Users:nlavabre:Documents:Projects:Test XML:" & outputFileName
try
set outputFilePointer to open for access file outputFilePath with write permission
on error
try
close access file outputFilePath
end try
end try
-- do something
close access outputFilePointer
I’d like to avoid having a giant try-end try with all my body code.
Then I guess if the file has not been closed properly then the next time I run the script I have an error and the second time it’s ok?
An open access to a file belongs to the application which opened it, which is the application running the script unless the ‘open for access’ is in a ‘tell’ statement. So if you’ve screwed up while developing a script in a script editor, leaving a file (or files) open, a simple expedient is to save your work and quit the editor. This will automatically close its accesses to any file it has open. You can then reopen the editor and continue.
Once you’ve got accesses properly protected by ‘try’ blocks in your script, you shouldn’t need any special measures in the script itself to close files which may have been left open last time ” unless there’s another, faulty script on your system leaving them open, in which case you’ll obviously edit that.
Generally:
An open access to a file belongs to the application which opened it and only that application can use it. When the application quits, all its open accesses are closed.
There can be several read-only accesses open to the same file at the same time ” belonging to the same application or to several ” each with its own file mark (ie. index into the file). When using ‘open for access’, it’s safer and more efficient to use the returned reference number with the other File Read/Write commands than to use an alias or file specifier. Similarly, only use an alias or file specifier with ‘read’ and ‘write’ if you know the application running the script doesn’t already have the file open for access.
Only one write-permission access can exist to a file at any one time, so it’s vital to close this if it’s accidentally left open.
That’s exactly what my script does… delete the delay part
EDIT: a more simpler but same approach would be
set theFile to (choose file) as string
set myString to stringFromFile(theFile)
if myString = null then
--second attempt
set myString to stringFromFile(theFile)
end if
on stringFromFile(theFile)
try
set fd to open for access file theFile
set theContent to read fd as string
close access fd
on error
close access file theFile
set theContent to null
end try
return theContent
end stringFromFile