我有问题。当我从服务器获取文件时,即使我的文件被下载但我收到错误“此文件正在被其他应用程序使用”
编辑:对不起,我的代码丢失了。这是服务器部分。我在启动后执行此方法。并等待来自客户的命令。 goto是一个标签。 ıf工作(例如“文件启动”)完成然后清洁和免费连接。这是多线程套接字应用程序。重复直到部分文件下载。我希望我会解释。
我的代码
procedure ConnectionWorker(P: Pointer);
label cleanup;
Var
sData1: TStringDYNArray;
cSock: TClientSocket;
scHost, scSendData, scFirstData, scFullData:String;
sBuff, sString:String;
bPackInfos:TPacketInformation;
scByte, sComm:Byte;
sBitMap:TBitmap;
sJPEG:TJPEGImage;
fFile:TFileStream;
scPort,lRecvLen, cRead, x,y:Integer;
arrBuffer:array[0..1000] of Byte;
bBuff:array[0..4095] of Byte;
eRatio:Extended;
sFirstCap, sDifCap, sSecondCap, sCompStream:TMemoryStream;
pCompStream:TCompressionStream;
cThread, cKillThread:Cardinal;
Begin
scHost := PInfo(P)^.scHost;
scSendData := PInfo(P)^.scData;
scPort := PInfo(P)^.scPort;
scByte := PInfo(P)^.scPackHead;
sFirstCap := TMemoryStream.Create;
sSecondCap := TMemoryStream.Create;
cSock := TClientSOcket.Create;
cSock.Connect(scHost,scPort);
if cSock.Connected then begin
scFirstData := scSendData;
If SendPacket(cSock,scByte, scFirstData) then begin
repeat
scFullData := '';
ZeroMemory(@arrBuffer[0], 1001);
lRecvLen := cSock.ReceiveBuffer(arrBuffer[0],1001);
if cSock.Connected = false then break;
SetLength(sBuff,lRecvLen);
MoveMemory(@sBuff[1],@arrBuffer[0],lRecvLen);
scFullData := scFullData + sBuff;
repeat
bPackInfos := VerifyPacket(scFullData);
scFullData := bPackInfos.PacketLeft;
sString := bPackInfos.PacketCommand;
sComm := bPackInfos.PacketByte;
if bPackInfos.PacketFinished = False then
break;
case sComm of
PACK_QUERYCOMPRESSEDFILE:
begin
if FileExists(sString) then begin
try
sFirstCap.LoadFromFile(sString);
sFirstCap.Position := 0;
sCompStream := TMemoryStream.Create;
pCompStream := TCompressionStream.Create(clMax,sCompStream);
pCompStream.CopyFrom(sFirstCap, sFirstCap.Size);
pCompStream.Free;
sString := '';
SetLength(sString,sCompStream.Size);
SendPacket(cSock,PACK_COMPRESSEDTRANSFERFILE,IntToStr(sCompStream.Size));
sCompStream.Position := 0;
sCompStream.Read(sString[1],sCompStream.Size);
SendPacket(cSock,PACK_COMPRESSEDDOWNLOADFILE,sString);
except
SendPacket(cSock,PACK_COMPRESSEDTRANSFERFILE,IntToStr(0));
end;
goto cleanup;
end;
end;
PACK_QUERYFILE:
begin
if FileExists(sString) then begin
try
sFirstCap.LoadFromFile(sString);
sFirstCap.Position := 0;
sString := '';
SetLength(sString,sFirstCap.Size);
SendPacket(cSock,PACK_DOWNLOADFILE,IntToStr(sFirstCap.Size));
sFirstCap.Read(sString[1],sFirstCap.Size);
SendPacket(cSock,PACK_TRANSFERFILE,sString);
except
SendPacket(cSock,PACK_DOWNLOADFILE,IntToStr(0));
end;
goto cleanup;
end;
if FileExists(sString) then begin
try
fFile := TFileStream.Create(sString, fmOpenRead);
Repeat
ZeroMemory(@bBuff[0],4096);
cRead := fFile.Read(bBuff[0],Length(bBuff));
If (cRead <= 0) Then Break;
If cSock.SendBuffer(bBuff[0],cRead) <= 0 then break;
Until 1 = 3;
fFile.Free;
except
end;
end;
goto cleanup;
end;
PACK_FILESTART: // problem is here
begin
try
fFile := TFileStream.Create(sString, fmCreate);
Repeat
ZeroMemory(@bBuff[0],4096);
cRead := cSock.ReceiveBuffer(bBuff[0],4096); --> stopped on debug. no execute next line.
if cRead <= 0 then break;
fFile.Write(bBuff,cRead);
Until 1 = 3;
Finally
fFile.Free;
end;
goto cleanup;
end;
end;
until scFullData = '';
until 1 = 3;
end;
end;
cleanup:
try
sFirstCap.Free;
sSecondCap.Free;
except
end;
FreeMem(p);
cSock.Disconnect;
End;
答案 0 :(得分:0)
一些想法......
1)代码不检查字节是否可供读取。见行: “cRead:= cSock.ReceiveBuffer(bBuff [0],4096); - &gt;在调试时停止。没有执行下一行。” 并注意这是如何在重复循环中。如果没有更多数据要读,会发生什么? (例如过早断开连接)
2)看起来它有重入代码...我没有看到任何检查阻止两个不同的线程试图在同一个文件上获取fmCreate
3)关于goto的评论,这似乎是从VBA(ON Error Gosub)转换而来的。我强烈建议为Delphi写一些更原生的东西
希望这有帮助