• C

How to check if a file is currently open for read/write by another process on windows

I need to do two things in a C/Java program.
1) Rename a file. How can I check if that file is opened for READ OR WRITE by another process. If it is opened for READ, how can I force windows to rename that file.
2) Read file, ONLY when no other process is currently writing to the file.

Thanks.
chennarhAsked:
Who is Participating?
 
ankuratvbConnect With a Mentor Commented:
Some more information:

According to both Micro$oft and Borland, Windows operating systems have no easy way to get the information that you desire.  The Borland C++ Builder runtime libraries support this, but to use it your application will have to be compiled and linked in the C++ Builder environment.  (I like Borland's compiler, IDE, and libraries so this something that I would do if it were my application.)

Interestingly, DOS 3.x allowed you to place such restrictions on file accesses, but as C has evolved I guess that they "fixed" that.  :(

If you're wanting "exclusive use" of the file, there are several things that you can do.

Use the lock() API in io.h to set a lock over the entire file.  Other applications will be prevented from reading or writing anything under the lock() until you release it.


Create a "lock file".  When your application wants use of the file:

open ("MyFileName.lck", O_CREAT|O_EXCL|O_TRUNC);

If the open fails, the lock already exists and the application should not open the file.  If the open succeeds, no other program that adheres to your locking protocol has the file and you can use it freely.  Once you close the file you must delete the lock file.

From:
http://oldlook.experts-exchange.com:8080/Programming/Programming_Languages/C/Q_20819103.html

http://oldlook.experts-exchange.com:8080/Programming/Programming_Languages/C/Q_10230526.html
0
 
ankuratvbCommented:
For renaming,use the rename() function defined in stdio.h
0
 
ankuratvbCommented:
For checking file status,you could use the stat() function.
It gives you the time last opened which you could use.
It also gives you the value of read and write bits which tell you whether this user has these permissions on this file or not.
0
Worried about phishing attacks?

90% of attacks start with a phish. It’s critical that IT admins and MSSPs have the right security in place to protect their end users from these phishing attacks. Check out our latest feature brief for tips and tricks to keep your employees off a hackers line!

 
grg99Commented:
What are you REALLY trying to do?

If you give us some more details, we may be able to help.

0
 
chennarhAuthor Commented:
I have a program (lets call it REPORTWRITER) (no source code) that creates a report(text file with name RPT001.txt), many times a day. And these are huge reports, 500-800MB. I have a web application that allows to view these reports page by page in browser.
I am using a simple servlet, that opens the report file, reads the requested page, and keeps the filestream open, so that next page can be read faster. Everything is good, except I donot know if the RPT001.txt is still being written to. I want to open the file only after REPORTWRITER is completely done writing to RPT001.txt. (This is my issue 2).
Now when we think life is not that bad, the next issue comes up.  We already have our RPT001.txt, an hour later REPORTWRITER is ready to create report again, it will overwrite the existing RPT001.txt. I need to preserve all reports, so I need to write a program to rename the exisiting RPT001.txt to RPT001TIMESTAMP.txt, before the REPORTWRITER begins to overwrite. Also, if the servlet has this file opened, I should force windows to close that stream and go ahead with renaming. (This is my issue 1).

hi ankuratvb,
i appreciate your response, I am aware of rename() and stat() functions, but I donot see how they will help in my context. I did not find lock() in io.h, i see only _lockfile(..) which lets you lock bytes in a file.
0
 
ankuratvbCommented:
One thing you might do is:

create a temp file the moment you start writing.
Delete the file when you finish writing.

When you're checking if writing is being done on the file,just try to open the temp file.
If it opens,it means writng is not done so wait.The moment its not able to open the temp file,you can now write to the file.

0
 
ankuratvbCommented:
For the renaming purpose:

Since you always write to RPT001.txt
You can do:

#include <stdio.h>
#include <time.h>

   char fn[100];//say for e.g.
   char *ptr;
   time_t t;
   strcpy(fn,"rpt001");
   time(&t);
   ptr=ctime(&t);
   strcat(fn,ptr);
   strcat(fn,".txt");
   rename("rpt001.txt",fn);

You could check the return value of rename to check if renaming was successful.
0
 
chennarhAuthor Commented:
unfortunately, all my problems stem from one issue.  the program that writes these files is not in my control. as i mentioned eariler, i do NOT have source code for that.  
I am checking to see if there is any simple solution, before I try to seek changes to that WRITER program. Once I get that source code, I was planning on modifying that program to write to RPT001TIMESTAMP.txt directly using temp file, and all I have to worry is to change my servlet to read from appropriate file.
And ofcourse, I am curious too.
0
 
ankuratvbCommented:
Since the programs purpose is to write the report,You could before calling that program create the temp file and delete it when the program ended.

I am not sure whether you can force closing a stream which another application has opened.

0
 
grg99Commented:
Is REPORTWRITER run or can be run from a batch file?
If so, something like this should work:

:TOP
REPORTWRITER
move rpt001.txt Archives\%Date%:%time%
sleep 3600
goto TOP

----------------
This simple script makes sure the file is done being written, then renames it into the directory of known good files.


0
 
ssnkumarCommented:
Every open file will have a file descriptor. This will be stored in a table which every process will be having.
Using this descriptor, you can look in a global table called file table. In this table, all the open files will have a reference number. If this number is 1 or greater, then that means the file is open, otherwise not.

To do the above operations, you must be a root user and also you will have to know the kernel data structures and their usage. I am not aware of any library call which does this!

-ssnkumar
0
 
ankuratvbCommented:
Hi ssn,

In windows,its not very easy to do(in fact,i dont think you're allowed to that,its M$ after all)
This is possible,though,in Unix.

0
 
anupvijayCommented:
Regarding Issue 2.

Does the REPORTWRITER open the RPT.txt file once before it starts writing and closes only when it if finished with it?

I mean if we find out in some way that the report file is not in use then can we be sure that the REPORTWRITER will not
open it for another hour ?

Cheers.
0
 
anupvijayCommented:
I dont know whether this fits into your requirement.
But can ponder on.......

How about having a small monitor program that keeps checking whether the report file is being updated ?
Now here the problem is that what property of the file will you monitor to find out that the file is not in use.

It could be time of access, size of file (depends how frequently the file is being written into etc.) or any other
parameter.
I suggest this because I assume that there is a space of 1 hour between the last access and the next access by the
REPORTWRITER.

Now if you can monitor this report file and somehow judge that it is not in use for a considerable amount of time(say 55
minutes) then you can rename this file with timestamp and then use this file for your web generated report rather than
using the live report file.

Did that make sense ? Come on.......experts.........let ideas pour in...........
Cheers.


0
 
chennarhAuthor Commented:
grg99,

The ReportWriter runs as a service.

anupvijay,

Yes, ReportWriter opens file in write mode, writes data and closes the file. It does not write partially, and later on open in append mode. And we donot know how frequently this file is created, i see 10 in a day, sometimes only 1, sometimes 4 within an hour with only couple of minutes gap between.....  does all this matter ???

Guys!!! It seems there is no solution for this problem on windows, without altering the REPORTWRITER process, so, I will go ahead and do that. Meanwhile, I welcome your thoughts and ideas, so that we all can share knowledge.
0
 
anupvijayCommented:
I thought you said you have no access to reportwriter code...!!!
0
 
chennarhAuthor Commented:
Well, I meant I do not own that code, but I can get to that.
0
 
ssnkumarCommented:
Hi chennarh,
If you can lay your hands on the REPORTWRITER process, then I think the easy solution is to maintain another file (say fileopen.txt). Create this file when the REPORTWRITER file is open and delete it once that file is closed.
So, the other process has to only check if this fileopen.txt file exists. If it is then, that means the REPORTWRITER file is still open. Otherwise it is closed and this process can modify that file.

-ssnkumar
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.