Hi,
I'm seeing a 'File is in use' error when I try to read a SAS log file from a batch job that completed. I can bring the log up in Notepad. I copied the file (with the copy command in a command window) to a test file and could read that just fine.
The code is pretty simple:
filename in 'c:\temp\prodrun.log';
data check;
infile in missover pad;
input line $1000.;
run;
filename in 'c:\temp\prodrunx.log';
data check;
infile in missover pad;
input line $1000.;
run;
On the first step, I'm getting:
ERROR: File is in use, c:\temp\prodrun.log.
Why would Notepad be able to bring a file up and SAS can't?
Am on 9.4 TS1M5 on a Windows 2012 server.
Thanks!
--Ben
Different programs deal with how other programs may be using a file differently. And some programs when they open a file "lock" access so no other application can use the file. And some can read "locked" files but won't be able to write to the file. So sometimes the type of access desired may or may not be available.
By default the SAS Filename statement in effect requests read and write access. So if another program has the file in a mode restricting write access you may have this issue.
General approach: Make sure that no other program, or in a shared environment other user, has the file open;
Thanks. I had looked for a 'read only' option in the filename options but couldn't find anything.
One approach that just occurred to me would be to use the PIPE option and a 'type xxx' argument. I think that would circumvent the issue, if not solve it.
This job runs from a scheduled batch file and when it completes, a log analyzer program follows it in the same stream. So I'm not sure what could be locking it for exclusive use.
Thanks!
--Ben
Ideas to try.
Is it a timing issue? Has the batch job not really finished writing the file to disk before your second SAS job is running?
Is NOTEPAD running on the same machine (with the same userid) as the SAS process? Perhaps the machines (users) have different access rights to that location?
What happens if you eliminate the FILENAME statement and just specify the location directly in the INFILE statement?
On unix you can sometimes use cat to read the file and avoid some locking issue. Not clear if Windows has a similar solution.
Could still be a timing issue as many systems are setup to "write behind". So they tell the caller they are done writing but really they have just buffered the information in memory and they will finish up.
Another issue is that making a new file might trigger some automatic backup that temporarily locks the file.
You could try just waiting a few seconds before trying to read. SAS has a SLEEP() function.
Good points in general. In this context though SAS has closed the log file for hours. Even manual testing shows the error 12+ hours after the job finished.
Just tested the pipe option with a type command for the file and that worked. Doesn't really solve the issue but at least it doesn't error out now.
Thanks for all the ideas!
--Ben
please close the file when you run code
An application called Process Explorer (now a free download from MS) will tell you which process uses the file.
Were you ever able to resolve this? I am having the same issue on Windows Server 2012r2 with SAS 9.4m7 in batch mode.
Hi Mike,
I did finally get it resolved. I ended up adding a 10 second wait at the start of the code with a data _null_ step. The batch job that was producing the log file kicked it off as the last thing it did prior to termination and apparently I just needed a bit of lag time between the two.
Hope that will solve yours as well.
--Ben
Thanks, Ben. I am throwing the kitchen sink at it--including the sleep function--so I will see if it works tonight. I'm also using a version of this old lock-check macro: https://www.lexjansen.com/wuss/2011/coders/Papers_Galligan_O_74889.pdf
filename _all_ clear; *clear any active filerefs;
%put NOTE: Checking for lock on &&JN&i log;
%do j=1 %to 10;
%put NOTE: &=j;
%CheckForLock(file=&&LogFileNameB&i)
%put NOTE: &=OpenYN;
%if &OpenYN^=YES %then %let j=10; *end loop if file not locked;
%if &OpenYN=YES %then %do;
data _null_;
x=sleep(10);
run;
%end;
%end;
filename in&i (&&LogFileName&i);
*read in log;
data LogContents&i._a;
infile in&i dsd dlm='|' TERMSTR=CRLF;
length log $134;
input log $;
n=_n_;
run;
filename in&i clear;
Hi, Could you try this program?
filename in PIPE 'type c:\temp\prodrun.log';
data check;
infile in missover pad;
input line $1000.;
run;
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.