tags:

views:

156

answers:

5

I have an application which accesses files on the intranet. The users can copy the files from the server located on the network to their local PCs. I have encoutered a problem with initial connection. i.e. when the application is started. The user searches for the file in the database. When he finds a file he wants to download he clicks on the name and the application downloads it. The first time download operation takes about 8-12 seconds just to initial the download and see the progress bar. The next downloads are almost instant. The file size varies between 1 MB to 15 MB.

Here is my code:

 const
 projectFilesURL = '\\IntranetServer\Directory\filesLocation\';

    procedure form1.GetSelectedFile(const fileName: string);
    var
    sourceFile: string;
    begin
    { \\IntranetServer\Directory\filesLocation\userSelectedFile.zip}
    sourceFile := projectFilesURL + fileName;    

      if FileExists(sourceFile) then
      begin

       fileCopy(fileName);
       lblSearching.Hide;
       AnimSearching.Hide;

      end
  else
  MessageDlg(
    'The file was not found on the server'
      , mtInformation, [mbCancel], 0);
 end;

end;
procedure form1.fileCopy(const sourceFile: string);
 var
   SourceF, DestF: file;
   Buf: array [0 .. 1023] of byte;
   NumRead, FSize, BytesCopied: Integer;
   destinationPathandFile: string;
begin
  destinationPathandFile := ExtractFilePath(ParamStr(0))
    + exportPath + sourceFile;
try
  AssignFile(SourceF, projectFilesURL + sourceFile);
  AssignFile(DestF, destinationPathandFile);
  FileMode := 0;
  Reset(SourceF, 1);
  Rewrite(DestF, 1);
  FSize := FileSize(SourceF);
  BytesCopied := 0;

 fileCopyProgress.Percent := 0;
  while not Eof(SourceF) do
  begin
    BlockRead(SourceF, Buf, SIZEOF(Buf), NumRead);
    BlockWrite(DestF, Buf, NumRead);
    Inc(BytesCopied, NumRead);

   fileCopyProgress.Percent := (BytesCopied * 100) div FSize;
   Application.ProcessMessages;
end;
CloseFile(SourceF);
CloseFile(DestF);

except
  on E: Exception do
  begin
  raise Exception.Create('Error occured while copying a file');

  Exit;
end;

end;

I am not sure where could be a choking point...maybe fileExists is not necessary. Since a file is on the server or not...maybe to throw exception is better... I appreciate any suggestions. Thanks,

A: 

in GetSelected:

  if FileExists(sourceFile) then

What is in sourceFile?
Certainly not (projectFilesURL + fileName) which is what you might want

François
Hi Francois, I have updated my code. Yes, sourceFile is exactly a concatenated string of projectFilesURL and fileName.
Greener
+1  A: 

You say that a second copy is almost instant, so a fundamental problem with your code is almost certainly excluded (and I don't see any fundamental problems in the copy code itself anyways). Have you tried stepping through the program in the debugger to see on what line it "hangs" or spends abnormal amounts of time?

A problem with comparable symptoms that I've see before is when a Windows client copies off a Linux Samba server, with somewhat older Samba versions : it takes a lot of time to "get connected", after that everything works at normal speeds.

As a more general remark, I'd work towards a better separation of concerns, having a filecopy method in a form object is not really state of the art...

fvu
Thanks for your answer, I will move a fileCopy to a class.
Greener
+1  A: 

this may help: Delphi Fast File Copy

Joe Meyer
Thanks for the link Joe, It is a good example, I will see if I can implement it with my program.
Greener
A: 

I'm not sure if this is your problem, but browsing,working with and copying files from mapped (where you have assigned a drive letter to a network drive) is much quicker than using the UNC (\Intranet) notation. If you can map a drive for all you clients this may improve you performance.

Toby Allen
+1  A: 

Since this is a network resource, the most likely cause of the problem is the fact that the system must cache the source directory before it can start transferring files. Once the directory is cached your performance improves.

One way you can "reduce" this amount would be to request a file via a thread at program startup to "prime the pump". Just throw away the result. My suggestion would be to create a small "dummy" file that is only a few bytes in size.

Another option would be to write a simple server that you would run on the server to serve files to your program. The advantage of this approach is that you can easily add on the fly compression that might speed up your file transfers (depends on the type of data being transfered).

skamradt
Funny you mentioned a dummy file, but this is what I actually did. I connected and get a small file during loading splash screen. Not a perfect solution, but it works.
Greener