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(D开发者_StackOverflow社区estF, 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,
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...
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).
in GetSelected:
if FileExists(sourceFile) then
What is in sourceFile?
Certainly not (projectFilesURL + fileName) which is what you might want
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.
精彩评论