# Read / Write of files which may be in use by other software

I am using Mathematica 10.3.1.0 on a Raspberry Pi. I would like Mathematica to open, read from, write to and close a file which may sometimes also be accessed by some external software. I created the file "dead_letter_box.txt" in "Text Editor", saved it and closed the Text Editor. The following code then worked exactly as expected:

compactreadfile[filename_, fileextension_] :=
Module[{filelocation, file, contentsoffile},
filelocation = FileNameJoin[{NotebookDirectory[], StringJoin[filename, fileextension]}];
contentsoffile = {};
If[FileExistsQ[filelocation],
Print[contentsoffile];
Close[file];,
Print["The file does not exist"]
]
]

compactwritefile[filename_, fileextension_, contentsoffile_] :=
Module[{filelocation, file},
filelocation = FileNameJoin[{NotebookDirectory[],StringJoin[filename, fileextension]}];
If[FileExistsQ[filelocation],
file = OpenWrite[filelocation];
Write[file, contentsoffile];
Close[file];,
Print["The file does not exist"]
]
]

fileextension = ".txt";

fileextension = ".txt";
variable = 7;
compactwritefile[filename, fileextension, variable]

fileextension = ".txt";


That is, the first read produced the output {}, the write produced no ouput, and the second read produced the output {7}. Moreover, when I opened the text file in the Text Editor, it contained the single character 7, as expected.

My problem is that these tests give exactly the same results, when I leave the text file open in the Text Editor. I had hoped Mathematica would return an error message, to the effect that the file is already in use by another program.

Is there a way to make Mathematica generate such errors ?

Checking that a file is in use by another application is very operating system dependent. As far as I know, Mahtematica doesn't support testing for this in user code.

Reading in a file that is in use by another app is harmless in itself. OpenWrite can be dangerous because it always deletes any pre-existing file before proceeding. So perhaps you should change the strategy you use in compactwritefile to

1. Refuse to write out to a file that already exists because OpenWrite always deletes any pre-existing file.
2. Make sure you close the file that you are writing to no matter what happens.

Here is a version of compactwritefile that uses this strategy.

compactwritefile[filename_, contentsoffile_] :=
Module[{filelocation, file},
filelocation = FileNameJoin[{$HomeDirectory, "Desktop", filename}]; If[FileExistsQ[filelocation], Print["The file already exists"], file = OpenWrite[filelocation]; If[file ===$Failed,
Print["Could not open file"],
AbortProtect[
Write[file, contentsoffile];
Close[file]]]]]


First test.

compactwritefile["test.txt", "This is another test."]


/Users/oldmg/Desktop/test.txt

Second test.

compactwritefile["test.txt", "This is a test."]


The file already exists

### Implementation notes

1. I think it is easier to omit the file extension as separated argument and let FileNameJoin do the string concatenation.
2. AbortProtect forces the file to be closed even it the write operation causes an abort condition.
3. It is good to test that the file has really opened before proceeding.