Page 1 of 1

Get success/error on file save

Posted: Thu Aug 01, 2019 11:28 pm
by Clyde
I want to save text to a file. Is there a way be notified or get a return value whether the file was successfully saved or not?

StringToFile() has no return value and OpenFile() with save mode also doesn't seem to help as I "just" get the id (when the file could be opened) but not the result of the writing operations.

Thanks!

Re: Get success/error on file save

Posted: Fri Aug 02, 2019 12:15 pm
by amyren
Just a thought, could it be an option to use fileattributes to check the time the file was last modified, and check again after writing and compare the result?
If the time of modification have changed, it should indicate that the file have been updated succesfully.

Re: Get success/error on file save

Posted: Fri Aug 02, 2019 1:26 pm
by amyren
This does seem to work
Note that the last fileattribute command could have been done just before the previous closefile, avoiding the need to open the file again.
I just did it this way to have a separate section to make the example more clear.

Code: Select all

	;creates an empty file in case it doesnt exist
	If Not Exists("save/inventory.data") 
		StringToFile("", "save/inventory.data")
		wait(50) ; add a delay just to make sure the timecheck will work
	EndIf	
	
	;open the file in readmode to check the modified date
	OpenFile(1, "save/inventory.data", #MODE_READ)
	old = FileAttributes(1)
	CloseFile(1)

	; check that the file is not protected before attempting to write
	If old.flags & #FILEATTR_READONLY
		DebugPrint("File is READONLY")
	Else
		OpenFile(1, "save/inventory.data", #MODE_WRITE)
		For i = 0 To ListItems(inv$) -1
			WriteLine(1, inv$[i])
		Next
		CloseFile(1)
	EndIf
	
	;Open the file again to check the time of modification
	OpenFile(1, "save/inventory.data", #MODE_READ)
	new = FileAttributes(1)
	CloseFile(1)
	If new.time > old.time 
		DebugPrint("SUCCESS")
		DebugPrint("Before: "..old.time.."   After: "..new.time)
	Else
		DebugPrint("File not updated")
	EndIf
By the way.
Andreas, if you are reading this
The example in the docs for fileattributes needs correction

This is copied from the docs

Code: Select all

OpenFile(1, "test.txt")
t = FileAttributes("test.txt")
Print(t.time)
If t.flags & #FILEATTR_READ_USR
  Print("#FILEATTR_READ_USR is set.")
Else
  Print("#FILEATTR_READ_USR is not set.")
EndIf
It expects a number as argument, so it must be like this to work:

Code: Select all

OpenFile(1, "test.txt")
t = FileAttributes(1)
Print(t.time)
If t.flags & #FILEATTR_READ_USR
  Print("#FILEATTR_READ_USR is set.")
Else
  Print("#FILEATTR_READ_USR is not set.")
EndIf

Re: Get success/error on file save

Posted: Fri Aug 02, 2019 3:31 pm
by jPV
I guess Hollywood gives an error if a write doesn't succeed, and exits (quits) the program unless you handle it otherwise.

So, if you want to check it, at least one way to do it is to disable internal error handler and check yourself.

Something like this:

Code: Select all

s$="blabla"
f$="ram:bla.txt"
ExitOnError(False)
StringToFile(s$, f$)
err=GetLastError()
ExitOnError(True)
If err
    err$=GetErrorName(err)
    DebugPrint("Write failed. Reason:", err$)
EndIf
I think that should be enough for all cases, but if you want to double check, you could compare the data and file sizes, like this:

Code: Select all

If ByteLen(s$)<>FileSize(f$)
    DebugPrint("Written size differs for some weird reason?!")
EndIf

Re: Get success/error on file save

Posted: Wed Aug 07, 2019 12:25 am
by Clyde
Thanks a lot for your suggestions! I also thought about the file date attribute. jPV's solution is also very need and probably more fitting.

Currently I am on vacation so I probably cannot test your solution and built it in my poject but will do afterwards. Also sorry for the late reply (also because of vacation).

Re: Get success/error on file save

Posted: Thu Aug 08, 2019 7:54 pm
by airsoftsoftwair
amyren wrote: Fri Aug 02, 2019 1:26 pm By the way. Andreas, if you are reading this The example in the docs for fileattributes needs correction It expects a number as argument, so it must be like this to work:
Thanks, fixed.

@all:
The easiest way to do this is to use Hollywood's new ?-syntax, so instead of the very cumbersome ExitOnError(False), call, GetLastError(), ExitOnError(True) route you could just do:

Code: Select all

If ?StringToFile("blabla", "ram:blabla.txt")
   DebugPrint("Error!")
EndIf
See here for details.

Re: Get success/error on file save

Posted: Thu Aug 08, 2019 11:35 pm
by Clyde
This is wonderful, thanks, Andreas!