5

I have some problems on files which are placed in a LAN: there is a single Delphi program (server) which should write some files, which can be only read by multiple Deplhi programs (clients). I use these simple instructions in the server for writing (DataList is a TStrings):

Stream:=TFileStream.Create(filePath,fmOpenWrite or fmShareDenyWrite);
try
 DataList.SaveToStream(Stream);
finally
 Stream.Free;
end;

The clients check every 5 seconds if the file above is modified (by just checking the FileAge), and if modifications are occurred, they load the DataList in the following way:

try
 Stream:=TFileStream.Create(filePath,fmOpenRead or fmShareDenyNone);
 DataList.LoadFromStream(Stream);
finally
 Stream.Free;
end;

Normally everything works perfectly, but sometimes it happens that the server or the client raise an exception because "the file is in use by other process". I don't understand which is the problem: I tried many alternatives, but this can happen also with just the server and only one istance of the client running..

Any ideas?

Thanks!

Bosch
  • 51
  • 1
  • 2
  • 1
    Try to find out which process locks the file. It could be another process, e.g. antivirus, backup, indexing service. – Ondrej Kelle Jul 25 '12 at 15:15
  • I don't think so: the computer where the file is written runs Windows 2008 Server, but it's without any antivirus and the backup works during night. And, most important, if I run the server or the client program alone I don't have any problem, while if I run both together I always have collisions.. – Bosch Jul 25 '12 at 15:45
  • I had exactly the same problem. In the server, this may happen because two server instances try to write at the same time. In the clients, I dunno, I just carefully catch and gracefully ignore the exception, with a toughful comment in the code saying *it should never occur, but it does* – PA. Jul 25 '12 at 17:13
  • Do not let the client access the file on the server directly. How about exposing the file through a web server? – Hendra Jul 26 '12 at 09:28

1 Answers1

3

By design, network file systems can't be trusted. At least, NFS (in Linux) and SMB (in Windows) have no proven lock feature: concurrent access is not safe.

You need to use a Client-Server protocol to ensure that shared data is safe. You can use TCP/IP, HTTP or any other mean.

I recommend using a true service implementation, like DataSnap, RemObjects or our Open Source mORMot.

Arnaud Bouchez
  • 42,305
  • 3
  • 71
  • 159
  • I think I'll use the TCP/IP protocol (which I already use in the same programs for other data exchanges); the only bad thing is that I found that TCP/IP is slower than direct file acces.. Thanks to everybody! – Bosch Jul 26 '12 at 11:42
  • Why would TCP/IP be slower than file access? The network file system runs on top of TCP/IP. – David Heffernan Jul 26 '12 at 11:57
  • Maybe you're right, but I saw that reading small text files (located in a shared directory in a Windows Server 2008 computer) + sending them via TCP/IP (by Indy components) to the clients programs is visibly slower than directly reading the same files by the client computers.. Any ideas about this? – Bosch Jul 26 '12 at 13:18
  • HOT NEWS! I tried to test the same situation in a local directory (both the server and the client program running in the same Win 7 64bit PC, using files in the same PC, without network), and I found the same result: sometimes there is a "file used by other process" exception in the file-writing server or in the file-reading client. So the answer from Arnaud Bouchez doesn't explain the situation. I'm using Delphi Light Edition 7.3.4.3 (build 8.1).. – Bosch Jul 26 '12 at 15:43
  • 1. Network folders use a cache (this is one of the reason of its locking failure), so it is why it is faster than always sending the content via TCP/IP. You can achieve better speed by implementing some clever protocol over TCP/IP, with cache at client level. 2. About your problem with local directory, it indicates that your implementation is even worse than expected. You may use the [file locking API](http://stackoverflow.com/a/4406823/80901) in your case. But on the network, [even this API won't be safe](http://stackoverflow.com/questions/788517). – Arnaud Bouchez Jul 26 '12 at 16:15