问题
Is is possible to open a text file and read the contents while another application is updating the file, in such a way that it does not cause a lock conflict?
I need to monitor a log file from one application which is updated by another application each time an event occurs.
I do check if the file is in use before I try to read it, but that does not seem to work in all cases.
Thanks, Pieter
回答1:
it depends on how the first app open that file.
i.e when calling CreateFile API to open a file, there is dwShareMode param which tells the api how to open it (if this was given 0, it can't be accessed from other applications IIRC). otherwise there should be no problem with reading from that file. if im not mistaken, to check if that file is being opened read only u can call something like
CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) ;
回答2:
- Download Process Monitor from Sysinternals.
- Open the filter dialog and add a "path" filter for your log file.
- Start the log-writing application (I'll call this "logwriter").
- Look for and click on the event where logwriter does a CreateFile.
- Under "Detail", it should have "Desired Access: Generic Write". And it should have "ShareMode: Read", which corresponds to
FILE_SHARE_READ
in the call to CreateFile. What it means is, "I, logwriter, permit others to read my file". - Now run your log-reading application ("logreader"), and do the same exercise.
- The Detail should have "Desired Access: Generic Read". And it should have "ShareMode: Read, Write", which means, "I, logreader, permit others, including logwriter, to read and write to the log file".
Those are the most sensible values, I think, and they will prevent locking. Other combinations may be permissible. There is a table here.
Now, you haven't said what happens when it "does not seem to work in all cases". What to do next will really depend on the details. Hopefully the above will give you enough information to work out what is going wrong.
回答3:
You won't get a lock conflict because the writing application is very unlikely to have locked the file. Doing what you suggest generally works without problems (it's what the UNIX tail -f command does) and those minor glitches that do occur can be ignored. I've written a couple of log monitoring apps in te past that worked like this, with no problems.
回答4:
Try using FileSystemWatcher to get events when a file is updated.
A more delphi friendly link
回答5:
Quite apart from getting the file sharing to work right which may be impossible depending on what the other program requests, some programs will close the file between accesses.
I have had success in the past with my program waiting for the file to become available, then quickly opening it, grabbing the needed data and closing it. At least in DOS an attempt to access a locked file caused a few retries, and I bumped up this setting, so that if the other program tried for the file while I had it they would simply be delayed and never see an error.
I was even able to update the file (I made sure NOT to close it in between!) without the other program ever knowing a thing.
Ugly as sin but we couldn't change the other program so it was the only way to get the job done. It was deployed in-house for years, I never heard a peep from the users of that system. It finally went away when the machinery the other program controlled was retired.
回答6:
XpoLog will do the trick without changing your env or code, XpoLog log monitor
回答7:
Avar is right - you are at the mercy of the writing program here. If they are locking the file, then there are a couple of things you can do:
1 - Check for a change in the "last modified" date time - if that changes, then you know something has happened.
2 - If the mod datetime did change, then (depending on the size of the file) it might be good enough to create a copy of the file and check that.
回答8:
we use "Tail for win32",
i know its not delphi but it might be useful
http://tailforwin32.sourceforge.net/
来源:https://stackoverflow.com/questions/737053/log-file-monitor