VelvetElvis Posted January 23, 2012 Share Posted January 23, 2012 Here's a brief chunk of code that creates a text file and writes 10 lines to it.$handle = FileOpen("D:\temp\test.txt", 1) For $x = 1 To 10 MsgBox(0, "", "Press OK to write line to text file.") If FileWriteLine($handle, "This is line " & $x) = 0 Then MsgBox(0, "Error", "Error writing to file.") NextTwo things I'd like to knowIf the file is deleted half-way through the loop, no error is triggered. Input continues to be written, or so it seems, but the file is no longer there. Why is this??I'm putting together an app that captures user input (via barcode reader) to a text file. I want to make the app as bulletproof as reasonably possible. If someone deletes the text file I'm writing to half-way through a shift, a lot of time and data is lost. What's the best way to handle writing to a text file that may be open several hours? Should the file be closed after each write? (This needs to be very responsive, as scanning is very fast). Any recommendations or text file wisdom greatly appreciated. Link to comment Share on other sites More sharing options...
water Posted January 23, 2012 Share Posted January 23, 2012 (edited) Why would anyone delete such a file? To hide the file, set the hidden attribute. Or place the file on a network share and give only read permissions to everyone but you. Edited January 23, 2012 by water My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
VelvetElvis Posted January 23, 2012 Author Share Posted January 23, 2012 Why would anyone delete such a file?To hide the file, set the hidden attribute. Or place the file on a network share and give only read permissions to everyone but you.It's a busy network, with tons of users, many of which have little computer knowledge. Making the file hidden isn't an optimum solution for me.Why does the program continue without error? Where is the data going? What's the best way around this? To be honest, I'm looking for coding solutions rather than network or file changes. Link to comment Share on other sites More sharing options...
water Posted January 23, 2012 Share Posted January 23, 2012 Do you call function "FileClose($handle)" somewhere in your script? This will close the file and write the buffer to disk. If you don't close the file and just exit the script then - I think - the buffer is just dropped. My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
VelvetElvis Posted January 23, 2012 Author Share Posted January 23, 2012 Do you call function "FileClose($handle)" somewhere in your script? This will close the file and write the buffer to disk.If you don't close the file and just exit the script then - I think - the buffer is just dropped.I do prior to closing the application.Even adding this line to the sample code I posted doesn't change the behaviour at all:FileFlush($handle)This is baffling to me. Link to comment Share on other sites More sharing options...
water Posted January 23, 2012 Share Posted January 23, 2012 (edited) I think you will have to dive into WinAPI.au3 (comes with AutoIt) or WinAPIEX.au3 (has to be downloaded from this site) to lock the file so no one can delete it.Edit:Please have a look at this This opens a file without sharing. Edited January 23, 2012 by water My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki Link to comment Share on other sites More sharing options...
VelvetElvis Posted January 23, 2012 Author Share Posted January 23, 2012 Thank you water. _WinAPI_CreateFile() certainly looks like exactly what I need. Unfortunately, after looking at the help file for all the other WinAPI functions I need to work with the files, it appears to be beyond my level of understanding, e.g. $tBuffer = DllStructCreate("byte[" & StringLen($sText) & "]") I was hoping once open, I could use the native AutoIt FileWriteLine() but apparently not. Thanks for your efforts. Link to comment Share on other sites More sharing options...
VelvetElvis Posted January 23, 2012 Author Share Posted January 23, 2012 ... but I'd still like to know why my original code: $handle = FileOpen("D:\temp\test.txt", 1) For $x = 1 To 10 MsgBox(0, "", "Press OK to write line to text file.") If FileWriteLine($handle, "This is line " & $x) = 0 Then MsgBox(0, "Error", "Error writing to file.") Next doesn't trigger an error when the file is deleted 1/2 way through. : Link to comment Share on other sites More sharing options...
Mikeman27294 Posted January 23, 2012 Share Posted January 23, 2012 That is simple. FileWriteLine writes to the given position in a file. If the file doesn't exist, it creates the file then writes to (I believe) line 1. It is not used to detect whether the file still exists. to do that, place this before the filewriteline If Not FileExists($Handle) Then Msgbox(0,"Error","The given file was deleted") Link to comment Share on other sites More sharing options...
VelvetElvis Posted January 23, 2012 Author Share Posted January 23, 2012 That is simple. FileWriteLine writes to the given position in a file. If the file doesn't exist, it creates the file then writes to (I believe) line 1. It is not used to detect whether the file still exists. to do that, place this before the filewriteline If Not FileExists($Handle) Then Msgbox(0,"Error","The given file was deleted") Thanks. I figured I'd have to do that. It's sort of at odds with my interpretation of the help file entry: "Returns 0 if file not opened in writemode, file is read only, or file cannot otherwise be written to." If it doesn't exist, it certainly can't otherwise be written to. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 23, 2012 Moderators Share Posted January 23, 2012 VelvetElvis,If it doesn't exist, it certainly can't otherwise be written toAlthough I am far from expert in this field, I believe I can explain that. You need to remember that you are probably not writing to the file, but to a buffer somewhere in memory. So AutoIt believe that the "write" was successful because that is what Windows tells it - it is too honest to think that Windows is lying barefacedly! You still have the handle value which Autoit is using to identify the file (or really buffer). If the file is deleted, the handle may well be taken over by another file - so your data could well end up being written somewhere entirely different to where you think. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
kylomas Posted January 23, 2012 Share Posted January 23, 2012 VelvetElvis, If you use the "file exists" technique and you find that the file was deleted, than what? If you use a "open >write>close" technique and the file is deleted, than what? Even if you find a way to lock the file while in use and someone comes along and deletes it later, same result. Your problem is more one of design than code. You should do as water suggested and secure the file using access rights. kylomas Forum Rules Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill Link to comment Share on other sites More sharing options...
VelvetElvis Posted January 23, 2012 Author Share Posted January 23, 2012 VelvetElvis,Although I am far from expert in this field, I believe I can explain that. You need to remember that you are probably not writing to the file, but to a buffer somewhere in memory. So AutoIt believe that the "write" was successful because that is what Windows tells it - it is too honest to think that Windows is lying barefacedly! You still have the handle value which Autoit is using to identify the file (or really buffer). If the file is deleted, the handle may well be taken over by another file - so your data could well end up being written somewhere entirely different to where you think. M23Thank you Melba23. It's a little more involved than I had envisioned. I used to write data entry apps in Delphi, using dBase files. File locking and writing was a piece of cake. I thought text files would be even easier. Link to comment Share on other sites More sharing options...
kylomas Posted January 23, 2012 Share Posted January 23, 2012 VelvetElvis, Serializing the file is one problem. The problem that you are describing is more basic, the ability to delete the file. What stopped users from deleting your dBase files? kylomas Forum Rules Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill Link to comment Share on other sites More sharing options...
VelvetElvis Posted January 23, 2012 Author Share Posted January 23, 2012 VelvetElvis,If you use the "file exists" technique and you find that the file was deleted, than what?If you use a "open >write>close" technique and the file is deleted, than what?Even if you find a way to lock the file while in use and someone comes along and deletes it later, same result.If the file disappeared (and believe me, having worked in end-user support, I've seen the damage a well-meaning mouse user can do to entire directory structures by simply letting go of the left mouse button at the wrong time), at least I could cut the losses at that point, rather than the user scan for an entire shift and lose everything.Your problem is more one of design than code.You should do as water suggested and secure the file using access rights.kylomasI couldn't agree more, kylomas. I'd love to be able to lock the file write to it, then close it and release it.Opening the file isn't a problem, I'm just struggling with the help file concerning the WinAPI functions of writing to the open file, e.g. DllStructCreate(), DllStructSetData(). These are all foreign concepts to me, and I'll have to try and figure them out.If you or anyone else knows of an include file or wrapper someone might've written for dealing with files, I"m all ears. Link to comment Share on other sites More sharing options...
VelvetElvis Posted January 23, 2012 Author Share Posted January 23, 2012 VelvetElvis,Serializing the file is one problem. The problem that you are describing is more basic, the ability to delete the file. What stopped users from deleting your dBase files?kylomasNothing at all.. I guess my concern is deleting it while it's being written to. A write error would show up immediately, IIRC. As well, if someone else tried opening the file to write to it, they wouldn't be able to do it if I had exclusive access. With a text file, I don't have that luxury, near as I can tell.Hmm... maybe writing to a text file isn't such a great idea after all. Link to comment Share on other sites More sharing options...
kylomas Posted January 23, 2012 Share Posted January 23, 2012 VelvetElvis, Something like this will serialize access to a file, however, the more users the slower shit gets. There may also be the possible of deadly embrace or what some people call spinning (two or more waits for a resource owned by some other process). #include <winapiex.au3> #include <date.au3> Local $my_file = "c:tmpbar_code_data" write("my bar code string") Func write($str) While _WinAPI_FileInUse($my_file) ; if the file is in use ConsoleWrite(' file in use at ' & _now() & @lf) ; display message for testing Sleep(1000) ; wait 1 sec wend ; and try again Local $hfl = FileOpen($my_file,1) ; open for append FileWrite($hfl,$str) ; write junk FileClose($hfl) ; close the file $hfl = 0 ; release the handle endfunc Have you considered sqlite as a DB instead of the flat files. kylomas Forum Rules Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill Link to comment Share on other sites More sharing options...
Blinky Posted January 23, 2012 Share Posted January 23, 2012 you could save a copy of the file. write to both. if one is deleted copy the other one and continue writing to both. in diferent places ofcorse, even diferent drives. Link to comment Share on other sites More sharing options...
kylomas Posted January 23, 2012 Share Posted January 23, 2012 @blinky, Yes, I was thinking that same thing as a "stop gap" solution... kylomas Forum Rules Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill Link to comment Share on other sites More sharing options...
VelvetElvis Posted January 24, 2012 Author Share Posted January 24, 2012 VelvetElvis, Something like this will serialize access to a file, however, the more users the slower shit gets. There may also be the possible of deadly embrace or what some people call spinning (two or more waits for a resource owned by some other process). #include <winapiex.au3> #include <date.au3> Local $my_file = "c:tmpbar_code_data" write("my bar code string") Func write($str) While _WinAPI_FileInUse($my_file) ; if the file is in use ConsoleWrite(' file in use at ' & _now() & @lf) ; display message for testing Sleep(1000) ; wait 1 sec wend ; and try again Local $hfl = FileOpen($my_file,1) ; open for append FileWrite($hfl,$str) ; write junk FileClose($hfl) ; close the file $hfl = 0 ; release the handle endfunc Have you considered sqlite as a DB instead of the flat files. kylomas Thanks for the code. It hasn't been decided yet what the data will be imported into, but a CSV file would be perfect input for most anything, hence my thoughts of using a text file. I'm thinking more and more that I may dump the text file and go for either Access or Excel. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now