-1

I have a problem of permission deny when deleting the file.

fso = CreateObject("Scripting.FileSystemObject")
mytempstring= fso.OpenTextFile(filepath).ReadAll
fso.deletefile(filepath,True) 'this will generate an error of permission denied

Any suggestions here? Thank you!

LesFerch
  • 1,540
  • 2
  • 5
  • 21
tammy
  • 21
  • 4
  • 1
    Check that you have permission for deleting files. Also in some case the file is open (in use) and that is why it cannot be deleted. – topsail Feb 02 '23 at 22:18
  • I closed everything but still cannot delete the file. I believe fso.OpenTextFile makes the file open but I am not sure how to close it. – tammy Feb 02 '23 at 22:21
  • You could try to follow the example here: [reading-a-text-file-using-a-filesystemobject](https://riptutorial.com/vba/example/3221/reading-a-text-file-using-a-filesystemobject) - in short, set a reference to the file when you open it, then call `.ReadAll` on it, then `.Close` it using that same reference variable. – topsail Feb 02 '23 at 22:26
  • 1
    There are typos in the posted script. `Set` is missing from the first line and the parentheses must be removed from the third line. With those corrections, the script, as presented, will NOT throw an error on the `DeleteFile` because using `ReadAll` in that way will automatically close the file. The problem is probably caused by earlier code that is not shown. That is, some previous code or process opened or created the file and did not close it. – LesFerch Feb 03 '23 at 16:00

1 Answers1

0

OpenTextFile returns a TextStream that you can then close. The problem with your code is you keep no reference to it, and instead chains the ReadAll method.

In theory, this should be OK. By not keeping a reference to the TextStream object it's reference count will immediately become zero once the ReadAll method has completed. When the reference count to an object reaches zero the script engine knows it can now safely free the object, and the process of freeing a TextStream will automatically close the file.

Unfortunately there's a problem with this. Although you can be sure the script engine will free the object, you cannot be sure when it will free the object. Script engines usually implement performance tuning techniques, and one example would be not freeing an object immediately but deferring that until the engine is less busy or has a more opportune moment.

There are many examples of people experiencing unexpected/undesirable behaviour from the VBA garbage collector not freeing memory immediately, but here's one where it was causing excessive memory usage when running a script, but the problem didn't occur when stepping through the code because the garbage collector had plenty of idle time to free memory. Note Edward's second reply, where he suggests implementing a Sleep call just so the garbage collector has idle time to free memory.

With all this taken into consideration, if you want to be sure the file is closed by the time you come to delete it, you must take ownership of closing the file instead of relying on the script engine to do it when the reference count reaches zero, so try this...

Dim fso, myStream
Set fso = CreateObject("Scripting.FileSystemObject") 

Set myStream = fso.OpenTextFile(filepath)
mytempstring= myStream.ReadAll
myStream.Close

fso.deletefile filepath, True
Lee
  • 149
  • 1
  • 8
  • While this explanation sounds plausible, I have been unable to create a script that demonstrates the issue, nor could I find any documentation to support this answer (the provided link is for VBA and does not mention ReadAll) . Can you provide any documentation link or script example that shows that using ReadAll directly with OpenTextFile does not always immediately close the file? – LesFerch Feb 07 '23 at 15:34